知识卡片
投影的精确定义、空元投影与ALL BUT语法
内容
投影r{A,B,...,C}的精确定义是:标题为{A,B,…,C},主体由这样的元组x构成——
存在r中某个元组t,t在A、B……C上的取值分别等于x在这些属性上的取值。因为结果
必须是关系([[关系代数的闭包性质]]),”重复被消除”这件事在投影里是自动内建
的,这也是为什么SQL要表达真正的投影语义时”真的需要DISTINCT”(没有DISTINCT
的SELECT子句只是打了引号的”投影”,参见[[限制的精确定义与SELECT不是限制的
辨析]])。恒等投影(r{H},H为r的全部属性)原样返回r;更有趣的是空元投影
(r{},即不保留任何属性的投影,书中提醒”空元”这个术语容易和SQL式null混淆
最好少用)——它的结果只能是[[TABLE_DUM与TABLE_DEE关系代数中的0]]二者之一:
r非空时返回TABLE_DEE,r为空时返回TABLE_DUM,这是因为”属性为空集的所有元组”
必然都是同一个0-元组,因此不管r原本有多少行,投影到空属性集后要么”存在这唯一
一个0-元组”(对应DEE)要么”完全没有元组”(对应DUM),没有第三种可能。Tutorial
D还提供了ALL BUT语法,允许用”排除哪些属性”而非”保留哪些属性”的方式表达投影
(P{COLOR,CITY}等价于P{ALL BUT PNO,PNAME,WEIGHT}),这在关系度很高、只想
去掉少数几个属性时能省下大量书写。语法上投影运算符被赋予了比其他运算符更高的
优先级,例如P JOIN S{CITY}被解析为P JOIN (S{CITY})而不是(P JOIN S){CITY},
这个隐含优先级是使用Tutorial D嵌套表达式时容易踩坑的一个细节。
参考来源
- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第6章"SQL和关系代数
I:原始运算符"6.4节"投影"(源文件:OEBPS/text00063.html)
- 结论依据:原文明确"结果是个关系。因此,'重复消除了'。因而SQL表述方式中真的
需要DISTINCT……投影r{}……在r非空时返回TABLE_DEE,否则返回TABLE_DUM……
Tutorial D还允许投影以排除属性而不是保留属性的方式进行表达……Tutorial D中
使用表达式P JOIN S{CITY}表示的是P JOIN(S{CITY})而不是(P JOIN S){CITY}"。
- 原始内容:结果是个关系。因此,"重复消除了"……投影r{}……在r非空时返回
TABLE_DEE,否则返回TABLE_DUM……P JOIN S{CITY}表示的是P JOIN(S{CITY})而
不是(P JOIN S){CITY}。