整理存储在代码中的SQL查询的最佳方法?(还是应该?)[关闭]


13

我确信我不是唯一一个在看到一页充满SQL查询的代码时感到沮丧的人。ActiveRecord和其他ORM模式有助于减少项目中使用的大量SQL,但是在许多复杂查询的情况下,SQL的使用似乎不可避免。

我正在寻找有关如何与其余代码(或外部代码)一起组织SQL查询的意见,以防止其散布到各处?一个明显的想法是使用视图,但是在处理多个大型索引表等时,视图通常会成为性能问题的源头。

编辑1-我假设您已经将其分离到模型层中


3
这个问题在这里绝对合适-代码组织:“激发答案,解释“为什么”和“如何”。属于“设计模式”和“建筑”主题(来自常见问题解答
Michael K 2010年

1
我正要问同样的问题。我希望这里有更多答案。
Michael Kristofik

Answers:


10

对我来说,SQL是业务逻辑代码的基本部分(在很多情况下,是大多数)。如果尝试将其与对返回的数据进行操作的代码分开,则更容易使代码的可理解性和可维护性失去平衡。

在我看来,读取数据,处理数据,写入数据,搜索数据...它们都是相似的操作,最好放在同一位置。

如果您开始感觉到查询的重复工作,那么您可能需要一个数据库视图或一个可以封装数据库访问方面的对象。

另一个技巧是实际上拥有一个好的数据库查询方法。在我编写的软件(PostgreSQL,MySQL,SQL Server)中,我确保大部分查询操作可以作为单个代码语句进行。

GetValue(SQL, [transaction], [array_of_params])
GetRow(SQL, [transaction], [array_of_params])
GetRowList(SQL, [transaction], [array_of_params])
GetValueList(SQL, [transaction], [array_of_params])
Execute(SQL, [transaction], [array_of_params])

这些(大致)是我确定的主要函数调用,它们是我的“连接对象”的一部分。这取决于语言以及您实际实现的语言,但是我的意思是保持它非常非常简单而轻松。

总之,将SQL视为编程的本机部分,并且不要为了抽象而抽象。


1
一个很好的答案。也许我只需要退后一步,开始将SQL作为代码的一部分来看,而不仅是散布在其中。
jellyfishtree 2010年

1
“不要为了抽象而抽象”-好点。为了更易于理解的代码而进行抽象。
杰森·贝克

“另一个提示实际上是要有一个好的数据库查询方法”:我绝对同意。当业务逻辑更改时,只有一个地方可以修改代码,这对您有很大帮助。
Michael K 2010年

1
您将SQL放在哪里?是否将其编译到应用程序中并使用上述方法发送?
约翰尼2014年

根据OP对Jason Baker的回答“盯着一个巨大的SQL查询的桶……”的评论,这如何解决读取大块SQL文本的问题?
JeffO 2014年

0

通常,最好有一个单独的模型层。有许多企业设计模式为构建此模型提供了方法。


抱歉,我应该更具体...我已经假设您已经将它们分为模型层。但是,使用SQL代码仍然可以使模型层变得非常分散。也许这是不可避免的。在模型代码中令我惊讶的另一件事是基于某种逻辑“构建SQL查询”的代码...也许应该将其分离到自己的工厂之内...
jellyfishtree 2010年

2
@jellyfishtree-恐怕我不明白那是什么问题。我的意思是,您担心您的模型层可能会得到过多的模型代码?
杰森·贝克

有效的反驳。我担心可读性。好的模型代码通常很容易理解,但是盯着一个巨大的SQL查询的桶并没有完全理解它的含义。显然,要做的第一件事是正确地注释那些查询,但是它与好的自记录代码不同,并且这些类型的部分分散在整个模型中。我接受它,但是我想知道在模型中是否有更好的方法隔离或组织疯狂的SQL语句...
jellyfishtree 2010年

0

最好将模型层分为3个子层-“实体”,“存储库”和“服务”。这将使您分离关注点,并从业务逻辑中将SQL集中在一个地方。

在这种情况下,所有数据检索代码(包括复杂的SQL)都将位于存储库中。因此,存储库的目标是将复杂的SQL语句隐藏在诸如这样的自解释方法之后getUsersWithActiveSubscription()

实体使用getter和setter抽象实际的DB表字段名称,可以在DB字段类型和您的应用程序/编程语言中可用的类型之间提供某种数据转换。如果您的ORM支持-实体可以处理关联。

服务层是业务逻辑的地方。服务使用存储库检索实体,对其进行操作并将其存储回去。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.