为什么定位查询不好?

时间:2009-07-04 20:57:35

标签: sql tuples relational-algebra database-relations relational-model

我正在阅读CJ Date的SQL and Relational Theory: How to Write Accurate SQL Code,他认为位置查询很糟糕 - 例如,INSERT

INSERT INTO t VALUES (1, 2, 3)

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

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

现在,我知道第一个查询与关系模型不一致,因为元组(行)是无序的属性集(列)。我无法理解第一个查询中的伤害位置。有人可以向我解释一下吗?

9 个答案:

答案 0 :(得分:20)

第一个查询在表架构更改的任何时候都会中断。第二个查询适应任何架构更改,使其列保持不变,并且不添加无默认列。

执行SELECT *查询然后依靠位置表示法提取他们关注的值的人software maintenance supervillains出于同样的原因。

答案 1 :(得分:9)

虽然在模式中定义了列的顺序,但它通常不应被视为重要,因为它不是在概念上重要。

此外,这意味着阅读第一个版本的任何人都必须查阅架构,以找出值的含义。不可否认,这就像在大多数编程语言中使用位置参数一样,但在某种程度上SQL在这方面感觉略有不同 - 我当然更容易理解第二个版本(假设列名是明智的)。

答案 2 :(得分:5)

我并不关心这方面的理论概念(在实践中,表确实有定义的列顺序)。我更喜欢第二个到第一个的主要原因是添加的抽象层。您可以修改表格中的列而不会搞砸您的查询。

答案 3 :(得分:2)

您应该尝试尽可能少地使SQL查询依赖于表的确切布局。

第一个查询依赖于只有三个字段的表,并且按照确切的顺序。对表格的任何改变都将破坏查询。

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

虽然您不经常重新排列表格布局,但在表格中添加更多字段非常常见。

此外,第二个查询更具可读性。您可以从查询本身判断记录中的值是什么意思。

答案 4 :(得分:2)

尚未提及的一点是,您将经常使用代理键作为PK,使用auto_increment(或类似的东西)来分配值。对于第一个,您必须在那里指定某些东西 - 但是如果不使用它,您可以指定什么值? NULL可能是一个选项,但这并不适合考虑将PK设置为NOT NULL

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

答案 5 :(得分:1)

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

  • 您的查询对列顺序的更改是稳定的,因此维护工作的工作量会减少。
  • 列排序更好地映射人们的思维方式,因此更具可读性。将列视为“名称”列而不是第2列更清楚。

答案 6 :(得分:1)

我更喜欢使用类似UPDATE的语法:

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

这比两个示例都更容易阅读和维护。

答案 7 :(得分:1)

长期来看,如果您向表中再添加一列,除非明确指定列列表,否则INSERT将无效。如果有人更改了列的顺序,您的INSERT可能会默默地将值插入到错误的列中。

答案 8 :(得分:0)

我要再添加一个东西,即使在更改表之前,第二个查询也不太容易出错。我为什么这么说?使用seocnd表单可以(并且应该在编写查询时)直观地检查插入表中的列以及values子句或select子句中的数据是否实际上以正确的顺序开头。否则你最终可能会在Honoraria字段中放入社会安全号码,并向发言人支付他们的SSN而不是他们应该为演讲所做的金额(例子不是随机选择的,除非我们确实在实际发生之前抓住了它,因为目视检查!)。