13

我有一个有点复杂的查询,其中包含多个(嵌套)子查询,我想为应用程序开发人员提供这些查询。该查询是通用的,并在一组数据集上生成具有计算值的视图,并且开发人员预计只需要查询返回的一些记录(即它们将限制某些实体的 ID 或日期范围或某些的结果这样的)。

我可以看到 3 种方法来实现这一点:

  1. 让开发人员将查询嵌入到每个应用程序中,并根据需要添加自己的WHERE子句。
  2. 创建一个存储过程,它接受我希望开发人员需要的所有条件作为参数(为了论证,可以说我可以预测在可预见的将来需要什么),该过程将运行复杂的查询并过滤它根据传递的参数。
  3. 将查询实现为具有多个子视图的视图(因为 MySQL 不允许视图中的子查询),并让开发人员将其用作表并用于WHERE让每个应用程序应用他们需要的过滤器。目前我正在查看 3 个额外的子视图,主要是因为一些子查询被多次使用,并且将它们作为子视图执行可以防止重复 - 否则它可能会更糟;-)。

什么是更好的性能明智?(假设所有索引在所有情况下都是等效的)如果可能,请尝试最坏的情况。

你认为在代码维护方面什么会更好?

4

2 回答 2

7

我喜欢定义“好”的问题——您专门询问了性能和可维护性,这使得答案可以讨论这种权衡。

从性能的角度来看,只要查询和数据符合您的预期场景,我认为这 3 个选项之间可能没有任何区别。我会用 100 倍的数据进行测试,并可能会扩大“where”子句以查看会发生什么,但索引结构等更有可能影响性能,而不是您是否通过存储过程执行相同的 SQL查看,或从客户端应用程序。

回答这个问题的最好方法是测试它——当然,有许多具体的细节可能会使我们溢出者可以给出的一般“我期望 x、y 或 z”的答案无效。如果性能是一个关键问题,请使用数据库填充工具(Redgate make on,我过去使用过 DBMonster)并尝试所有 3 个选项。

从维护的角度来看,我会提供选项 4,在我看来,它是迄今为止最好的。

选项 4:构建一个数据访问库,其中封装了对您的数据的访问。让库公开方法和参数以优化记录的选择。考虑使用规范模式 (http://en.wikipedia.org/wiki/Specification_pattern)。使用库中最好的查询,不要用实现细节打扰开发人员。

如果这不起作用 - 异构应用程序代码,对于一个简单的要求来说变化太大 - 我将评估选项如下:

  1. 嵌入式 SQL:取决于此 SQL 被重用的次数,这可能没问题。如果只有一部分代码运行 SQL,它在逻辑上类似于数据访问库。然而,如果相同的代码片段需要在很多地方重复使用,那么它很可能是错误的来源——SQL 中的一个小改动需要在多个地方重复。

  2. 存储过程:出于维护原因,我通常不喜欢存储过程——它们往往会因过载而变得脆弱,并创建一种程序化的思维方式。例如,如果您对在单独的存储过程中使用此 SQL 计算有其他要求,您很快就会得到一个过程编程模型,存储过程相互调用。

  3. 意见:这可能是最好的选择。它将特定的数据逻辑放在一个地方,但提倡使用基于集合的逻辑,因为访问路径是通过 SELECT 语句,而不是通过执行过程语句。视图很容易合并到其他查询中。

于 2011-10-24T11:56:44.310 回答
3

如果实施得当,这三种解决方案中的任何一种都可以用于维护,但请记住在迁移过程(代码或数据库迁移)中如何处理它们中的每一个。

如果查询很大,则存储过程会因为发送较小的查询而减少带宽开销,从而为您提供一些额外的性能。您还可以通过此解决方案获得一些额外的安全性。

对于维护解决方案,我更喜欢第一种和第二种解决方案,因为您可以在不更改任何数据库的情况下对查询进行任何更改。如果您选择第一种解决方案,我会将查询调用包装在一个函数中,这样您就只有一个地方可以进行更改。

开发人员的角度来看,我会选择视图解决方案,因为它是最透明的,我的意思是它就像查询一个普通的表,你可以用一个 describe 命令检查表结构,或者只选择你需要的字段和条件查询,或加入另一个表等...

关于where 子句的灵活性,您可以使用任何建议的解决方案来实现它。您可以在包装函数中添加 where 参数 (1),您可以向存储过程添加 where 参数但要小心注入 (2),或者开发人员可以像往常一样在视图中添加 where 子句 (3)

请记住,在 MySQL 中,视图不是临时表,如果查询非常复杂,如果查询以不同方式大量使用(禁用缓存性能提升),则此解决方案不是最好的。我会考虑一个临时表解决方案(计数器表),它使用编程的任务/cron(例如一天、一周、任何需要时)更新每个时间段,或者通过设置 propper 触发器来更新。该解决方案可以大大提高性能。

希望这会有所帮助,我最喜欢视图解决方案,但从数据库的角度来看,开发可能更复杂。

于 2011-10-24T09:48:47.863 回答