我正在读 CJ Date 的 SQL 和关系理论:如何编写准确的 SQL 代码, ,他认为位置查询很糟糕——例如,这个 INSERT:

INSERT INTO t VALUES (1, 2, 3)

相反,您应该使用基于属性的查询,如下所示:

INSERT INTO t (one, two, three) VALUES (1, 2, 3)

现在,我知道第一个查询与关系模型不相符,因为元组(行)是无序的属性集(列)。我无法理解第一个查询中的危害在哪里。谁可以给我解释一下这个?

有帮助吗?

解决方案

第一个查询打破几乎任何时候表模式的变化。所述第二查询可容纳任何模式改变离开它的列完整和不添加defaultless列。

谁提取他们关心的价值观做SELECT *查询,然后依靠位置符号人们的软件维护的supervillains 中出于同样的原因。

其他提示

虽然列的顺序的在模式中定义,它一般不应被视为重要的,因为它不是概念重要的。

此外,这意味着任何人阅读的第一个版本有咨询的模式,找出哪些值是为了意思。诚然,这就像在大多数编程语言中使用位置参数,但不知何故,SQL觉得在这方面略有不同 - 我当然更容易理解的第二个版本(假设列名是明智的)

我真的不关心这方面的理论概念(在实践中,表确实有定义的列顺序)。主要的原因我宁愿第二个到所述第一是一个的加入抽象的层。您可以修改表中的列没有搞砸了你的查询。

您应该尽量让你的SQL查询依赖于尽可能少的表的准确布局。

第一个查询依赖于该表只具有三个字段,并且在确切顺序。在所有表中的任何变化都会中断查询。

在第二查询仅依赖于存在是在表中这三个felds,和字段的顺序是无关紧要的。您可以更改表中的字段的顺序不破坏查询,你甚至可以,只要他们允许空值或具有默认值添加字段。

虽然你没有重新排列表格的布局非常频繁,增加更多的字段的表是相当普遍的。

另外,第二查询是更具有可读性。您可以从查询本身告诉摆在记录中的值的意思。

这是尚未提到的东西是,你会经常有代理键作为你的PK,有auto_increment(或类似的东西)分配一个值。有了第一个,你必须指定的的东西的有 - 但你可以指定什么价值,如果它不被使用的? NULL可能是一种选择,但并不真正适合在考虑PK将被设置为NOT NULL

但除此之外,整个“锁定到特定的模式”是一个更加重要的原因,IMO。

SQL 为您提供了为 INSERT 和 SELECT 语句指定列名的语法。您应该使用它,因为:

  • 您的查询对于列排序的变化是稳定的,因此维护工作量更少。
  • 列顺序更能反映人们的思维方式,因此更具可读性。将列视为“名称”列而不是第二列更清楚。

我喜欢使用UPDATE状语法:

INSERT t SET one = 1 , two = 2 , three = 3

远远更容易阅读和维护比两者的实施例。

从长远来看,如果你添加一个列到你的餐桌,你的INSERT不会工作,除非你明确指定的列清单。如果有人更改列的顺序,你的插件可以静静地成功将值插入错误的列。

我要补充一点,第二个查询是不容易orginally误差表改变甚至之前。为什么这样说呢? Becasue与seocnd形式,你可以(也应该当你写的查询)目视检查,看是否在插入表中的列和数据值子句或SELECT子句中实际上以正确的顺序开始。否则,你可能最终把社会安全号码的酬金场意外和支付音箱的SSN,而不是他们应该做的演讲(例如随机没有选择,除了我们没有赶上之前它真的发生这要归功于量目视检查!)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top