为什么位置查询不好?
-
23-08-2019 - |
题
我正在读 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,而不是他们应该做的演讲(例如随机没有选择,除了我们没有赶上之前它真的发生这要归功于量目视检查!)。