除了第一个表单有重复的列之外,其他两个表单是否真的有优势?还是它们只是语法糖?NATURAL JOIN在某种简化常规SQL风格的关系编程中使用。这是因为1.它直接使用
谓词逻辑的简单运算符,这是工程(包括软件工程)、科学(包括计算机科学)和数学中精度语言,而且2.同时并且交替地直接使用
关系代数的简单运算符。 (尽管在嵌入SQL时会加上其余的SQL查询语法。)
常见的关于NATURAL JOIN的抱怨是,由于共享列不是显式的,在模式更改后可能会出现不适当的列配对。在特定的开发环境中可能会出现这种情况。但在这种情况下,有一个要求,即只连接某些列,并且没有PROJECT的NATURAL JOIN是不合适的。因此,这些论点假设NATURAL JOIN被不当使用。而且,争论者甚至没有意识到他们正在忽略需求。这样的抱怨是牵强附会的。(此外,良好的软件工程设计原则不会有这样具体规格的接口。)
同一阵营的另一个相关的错误抱怨是"NATURAL JOIN甚至不考虑外键关系"。但是 任何连接都是因为表的含义而存在,而不是因为约束条件。查询不需要约束条件。如果添加约束条件,则查询仍然正确。如果删除约束条件,则依赖它的查询将变得错误,必须更改为不依赖它的措辞,而这种措辞本来不需要更改。这与NATURAL JOIN无关。
你已经描述了影响的不同之处:每个公共列只返回一份副本。
来自
是否有任何经验法则可以从可读的描述构建SQL查询?:
事实证明,自然语言表达式、逻辑表达式、关系代数表达式和SQL表达式(最后两者的混合体)在相当直接的方式上对应。
例如来自
Codd 1970:
所描绘的关系称为组件。[...] component(x,y,z)的意思是部件x是部件y的直接组成部分(或子装配件),并且需要z个部件x才能组装一个部件y。
来自
这个答案:
每个基本表都有一个语句模板,也称为谓词,由列名参数化,通过它我们可以将一行加入或者排除。
将一行插入到谓词中会产生一个陈述,也称为命题。使命题为真的行进入表格,而使命题为假的行留在外面。(因此,表格陈述了每个存在行的命题,并且未存在行的命题并未被陈述。)
每个表达式值都有一个谓词,根据其表达式。关系模型的设计使得如果表T和U分别保存T(...)和U(...)行,则:
- T NATURAL JOIN U 保存T(...) AND U(...)行
- T WHERE condition 保存T(...) AND condition行
- T UNION CORRESPONDING U 保存T(...) OR U(...)行
- T EXCEPT CORRESPONDING U 保存T(...) AND NOT U(...)行
- SELECT DISTINCT columns to keep FROM T 保存THERE EXISTS columns to drop SUCH THAT T(...)行
- 等等
否则,对SQL进行推理是不“自然”的:
SQL SELECT语句可以代数地理解为:1. 隐式地将表的每个列C与(可能隐含的)关联名称T重命名为T.C,然后2. CROSS JOIN,然后3. 根据INNER ON进行RESTRICT,然后4. 根据WHERE进行RESTRICT,然后5. 根据SELECT进行PROJECT,然后6. 根据SELECT进行RENAME,删除T.,然后7. 隐式地重命名以删除剩余的T.。在T.-RENAMEings之间,代数运算符也可以被视为逻辑运算符,表名则是它们的谓词:T JOIN ... vs Employee T.EMPLOYEE has name T.NAME ... AND ...。但是,在SELECT语句内部的概念上,存在一个双重重命名引起的CROSS JOIN表,其中列名为T.C,而外部表的列名为C。
或者,可以将SQL SELECT语句在逻辑上视为:1. 在每个相关名称T和基本名称或子查询E周围引入,然后2. 使用T.C引用量化的T的值来引用其C部分,然后3. 根据FROM等构建结果行从T.C中,然后4. 根据SELECT子句命名结果行列,然后4. 离开的范围。再次,代数运算符被认为是逻辑运算符,表名是它们的谓词。但是,这在概念上具有SELECT中的T.C,但是在相关名称的C之外进出。
这两个SQL解释远不如仅使用JOIN或AND等“可互换”的方式直接明了。(您不必同意它更简单,但是这种感知是NATURAL JOIN和UNION / EXCEPT CORRESPONDING存在的原因。)(在预期用途之外批评此样式的论点是牵强附会的。)
USING是一种中间地带的孤儿,一只脚在NATURAL JOIN阵营,另一只脚在CROSS JOIN阵营。它在前者中没有真正的作用,因为那里没有重复的列名。在后者中,它或多或少只是缩写JOIN条件和SELECT子句。
“我可以看到后者的缺点在于你需要将主键和外键命名相同,这并不总是切实可行。”
PK(主键)、FK(外键)和其他约束并不需要进行查询。(知道某个列是其他列的函数允许标量子查询,但你总是可以重新构造。)此外,任意两个表都可以有意义地连接。如果你需要两个列具有相同的名称,则可以通过SELECT AS进行重命名。
dept
列,而其他两个不会。 - Manngo