知识卡片

并/交/差的精确定义与CORRESPONDING实践建议

操作参考卡

内容

并、交、差三个运算共享同一种结构:都要求r1、r2属于同一类型(标题相同),结果 也是同一类型的关系。并(Tutorial D的UNION,SQL的UNION)的主体是”在r1中出现、 或在r2中出现、或两者都出现”的元组;交(INTERSECT)的主体是”r1和r2中都出现”的 元组(呼应[[自然连接的精确定义及交与积是连接的特例]],交本质是标题相同这一 特殊情形下的连接);差(Tutorial D的MINUS,SQL的EXCEPT)的主体是”在r1中出现 但不在r2中出现”的元组,且差是严格二元的、没有多元版本。三者都自动执行[[关系 代数的闭包性质]]要求的”消除重复”,这一点上和投影一致;一个容易被忽视的实践 差异是:SQL的UNION默认就是DISTINCT语义(不同于SELECT子句默认ALL),所以对 UNION通常不需要额外指定DISTINCT。实践建议清单:确保参与运算的两个表在列名和 类型上能对应(哪怕位置不同);能用CORRESPONDING就用它,这样不用操心两表列的 先后顺序是否一致,用不了就手动调整SELECT列表顺序对齐;CORRESPONDING后的BY (列名列表)选项通常应省略,因为默认行为已等价于”BY 全部公共列”,显式写出既 容易误导(暗示运算元变成了这些列的投影)又是多余的;永远不要对UNION指定ALL—— 如果确实知道输入本身互不相交、只是想避免系统重复做”消除重复”的额外工作,那也 是纯粹的性能考量,不应作为默认习惯。Tutorial D额外提供D_UNION(不相交并,运算 元有重复元组时报运行时错误)和I_MINUS(包含差,第二个运算元必须完全被第一个 包含,否则报运行时错误),SQL对这两个变体都没有直接对应物。

参考来源

- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第6章"SQL和关系代数 I:原始运算符"6.6节"并、交和差"(源文件:OEBPS/text00065.html) - 结论依据:原文明确"它们的并,r1 UNION r2……构成其主体的元组是所有在r1中 出现、或在r2中出现、或在r1和r2中都出现的元组……UNION的缺省项就是DISTINCT 而不是ALL……确保第1个运算表的每一列都具有和第2个运算表的某一列相同的名称 和类型……如果可能就指定CORRESPONDING……永远别指定ALL……差是严格二元的—— Tutorial D不支持任何种类的'n元差'运算"。 - 原始内容:它们的并……构成其主体的元组是所有在r1中出现、或在r2中出现、或在 r1和r2中都出现的元组……UNION的缺省项就是DISTINCT而不是ALL……永远别指定 ALL……差是严格二元的。