我有一个带有多个子查询(嵌套)的比较复杂的查询,我想让应用程序开发人员可以使用它。查询是通用的,通过数据集的集合生成一个具有计算值的视图,开发人员只需要查询返回的一些记录(即,它们将限制某些实体的ID或日期范围等的结果)。
我可以看到三种实现方法:
让开发人员将查询嵌入到每个应用程序中,并根据需要添加自己的WHERE
子句。
创建一个存储过程,它接受我希望开发人员需要的所有条件作为参数(为了这个参数,假设我可以预测在可预见的将来需要什么),并且该过程将运行复杂的查询,并根据传递的参数对其进行过滤。d.
将查询实现为具有多个子视图的视图(因为MySQL不允许在视图中使用子查询),并让开发人员将其用作表,并使用WHERE
让每个应用程序应用所需的筛选器。目前,我正在查看3个附加的子视图,主要是因为一些子查询被多次使用,并将它们作为子视图来防止重复-否则情况可能更糟;-)。
什么是性能方面更好的?(假设所有索引在所有情况下都是等价的)如果可能的话,请选择最坏的情况。
你认为在代码维护方面什么更好?
最佳答案
我喜欢定义“好”的问题——您特别询问了性能和可维护性,这使得答案可以讨论这种权衡。
从性能的角度来看,只要查询和数据符合您预期的场景,我认为这3个选项之间就不会有任何区别。我将使用100倍以上的数据进行测试,并可能扩展“where”子句以查看会发生什么,但是索引结构等更可能影响性能,而不是从存储过程、视图或客户端应用程序执行相同的SQL。
回答这个问题的最好方法是测试它——当然,有许多具体的细节可能使溢出器可以给出的一般“我希望X、Y或Z”答案无效。如果性能是一个关键问题,请使用数据库填充工具(redgate make on,我以前使用过dbmonster)并尝试所有3个选项。
从维护的角度来看,我会提供一个选项4,在我看来,这是迄今为止最好的。
选项4:构建一个数据访问库,它封装对数据的访问。让库公开方法和参数以优化记录的选择。考虑使用规范模式(http://en.wikipedia.org/wiki/specification_pattern)。使用库中最好的查询,不要用实现细节打扰开发人员。
如果这不起作用-异类应用程序代码,对于一个简单的需求来说太多的变化-我将评估以下选项:
嵌入式SQL:根据重复使用此SQL的次数,这可能是正常的。如果运行SQL的代码只有一部分,那么它在逻辑上类似于数据访问库。但是,如果相同的代码片段需要在很多地方重复使用,那么它很可能是错误的来源——SQL中的一个小的更改需要在几个地方重复。
存储过程:由于维护原因,我通常不喜欢存储过程-它们往往会因过载而变得脆弱,并创建一种过程化的思维方式。例如,如果您对在单独的存储过程中使用此SQL计算还有其他要求,那么您很快就会得到一个过程编程模型,存储过程彼此调用。
观点:这可能是最好的选择。它将特定的数据逻辑放在一个地方,但由于访问路由是通过select语句,而不是通过执行过程语句,因此它促进了基于集合的逻辑的使用。视图很容易合并到其他查询中。