38

例如,如果您在查询中有 > 5 个左连接,那么代码有味道......

  • 你的设计有问题吗?
  • 你在一个查询中做的太多了吗?
  • 你的数据库太规范了?
4

8 回答 8

40

对于某些设计来说,这是一个完全合法的解决方案。

假设您有一个一对多关系的层次结构,例如Customer- Order- Basket- Item-Price等,它可以在任何级别上都未填充:aCustomer可能没有Orders,anOrder可以没有Baskets,等等。

在这种情况下,您会发出如下内容:

SELECT  *
FROM    Customer c
LEFT OUTER JOIN
        Order o
ON      o.CustomerID = c.ID
LEFT OUTER JOIN
        Basket b
ON      b.OrderID = c.ID
…

注意,在某些情况下可能效率低下,可以用EXISTSor代替NOT EXISTS(如果你只想弄清楚对应的记录存在或不存在于其他表中)。

有关性能详细信息,请参阅我的博客中的这篇文章:

于 2009-04-27T14:08:24.960 回答
12

从某种意义上说,这是您可以/应该调查的事情,我会说是的。通过从中考虑一些观点,您可能可以获得更好的实用性和维护性。

从某种意义上说,它是“坏代码”,不,这很容易合理,特别是对于较大的数据库,现代数据库可能会优化任何低效率。

于 2009-04-27T14:10:21.333 回答
9

不,这样做很好,但是如果您发现自己一遍又一遍地使用相同的连接到相同的表编写相同的查询/过程,它可能是创建视图的候选者,只是为了简化您将来的查询,并且减少架构更改时需要更改的接触点数量

于 2009-04-27T14:10:52.847 回答
8

很多时候你可以通过创建辅助视图来减轻视觉上的异味,我不认为有多少左连接被认为是不好的硬性规则。

与过程编码不同,将 SQL 分解成小块可能会导致查询效率低下。

于 2009-04-27T14:11:13.267 回答
4

你的结果我的变化

任何不寻常的东西都可能是任何东西的代码气味。就像 Quassnoi 所说的那样,它可能是完全合法的。真正深入的报告需要大量的连接来正确拼凑信息的情况并不少见。这并不意味着开发人员应该考虑对他们的数据库进行非规范化。

于 2009-04-27T14:12:08.133 回答
3

几乎不可能有人回答如此笼统的问题,并试图创建这样一个任意规则是没有意义的。

左连接是一种完全可以接受的连接类型,它映射到一个非常常见的需求:给我所有的 x,如果它们有关联的 y,那么也得到这些。

于 2009-04-27T14:11:45.543 回答
3

一点都不。构建在某些查询上使用大量左连接的数据库设计是完全合法的。

话虽如此,我通常更喜欢构建数据库,以便限制需要外部连接的情况,因为经验倾向于表明使用它们的(复杂)查询更容易出错并且可能会引起维护问题。

作为一个有趣的历史,IBM DB2 的早期版本仅在大型机上运行时不支持外部连接(当时 Oracle 和 Ingress 都支持,这是一个主要卖点)。这导致了数据库设计中的一些有趣问题,因为有必要确保仅使用内部连接就可以解决数据库的所有预期数据访问要求。

于 2009-04-27T14:15:53.117 回答
3

我认为必须使用许多连接(例如处理规范化数据)不是代码异味,而是表明您可能没有在正确的位置工作。根据我的经验,那些担心查询中的连接数量的人在数据库中开发得太多,而在公开数据的应用程序和报告中开发得不够多。数据结构必须足够灵活以支持无数用途,这就是为什么标准化在某种程度上很重要。

在构建当今的企业应用程序时,开发人员可以利用昨天的成就在 SQL 甚至 XML 等技术之上的抽象级别上工作,以便以更少的工作交付更多的价值。有一些工具,即报表编写器、代码生成器、ORM、实体框架等,可以抽象出手动构建 SQL 的低级工作,并为您执行连接。大多数人都知道正在使用的 SQL 方言(例如,Oracle 9 与 MySQL 3),并且可以生成对该方言最有效的 SQL 语法;这意味着他们可能比您更好地创建连接。

但是,这些工具在没有足够规范化的关系环境中工作得非常差,或者根本不能工作。对我来说,这就是“发展”气味表现出来的地方。如果一个已建立的数据访问工具无法理解我构建数据的关系,我可能需要寻找一种更规范的方式来创建这些关系,并从中获得远远超过使用该工具的好处。通常,介于第 2 和第 3范式之间的某个地方是甜蜜点。尽管总是存在一些小的关系数据区域,在这些区域中,更高程度的标准化是有意义的并增加了价值。

干杯,特拉维斯

于 2009-09-17T17:38:41.643 回答