知识卡片
Tutorial D与SQL属性对应方式的根本差异及SQL的高度冗余
内容
关系代数运算符具有通用性(对所有关系一视同仁,不需要为不同业务场景各写一个
专属连接运算符)和只读性(只读取运算元、返回结果,从不修改任何内容——它们
操作的是关系值而非关系变量,即使表达式里写的是关系变量名,那也只是借用变量
当时持有的值,就像N+2用的是变量N当时的值3而非变量本身),因此INSERT/DELETE/
UPDATE严格说不是关系代数运算符(尽管它们是关系运算符,学术界常见的相反说法
是不准确的)。在需要建立”运算元之间属性如何对应”这个问题上,Tutorial D和SQL
走了两条根本不同的路:Tutorial D要求参与连接类运算的属性必须是真正同一个属性
(同名且同类型),并在所有相关场合统一沿用这一套技术;SQL则因场景而异,有时
按位置对应(比如外键的FOREIGN KEY语法),有时靠显式声明(ON子句),有时要求
同名列(NATURAL JOIN)——同一个”按城市连接零件和供应商”的查询,SQL至少有
WHERE子句显式指定、ON子句、USING子句、NATURAL JOIN四种写法,语义完全等价。
这种技术上的不统一,加上SQL既支持关系代数特征又显式支持关系演算特征(相关
名称、EXISTS等),共同导致SQL成为一门高度冗余的语言——书中提到作者曾专门写过
一篇论文,证明”获得供应了P2型号零件的供应商名称”这样一个简单查询在SQL里可以
用50多种不同方式表达,这种冗余同时给用户和优化器都造成了实实在在的认知负担。
参考来源
- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第6章"SQL和关系代数
I:原始运算符"6.1节"一些预备知识"(源文件:OEBPS/text00060.html)
- 结论依据:原文明确"关系代数的运算符是通用的……运算符是'只读'的……在需要属性
对应关系时,Tutorial D认为所讨论的属性实际上就是一个属性……相反,SQL在不同
的场合使用不同的技术……SQL是一个高度冗余的语言,因为它提供了大量方式来实现
相同的查询……展示了在SQL中,即使是'获得供应了P2型号零件的供应商名称'这样的
简单查询也可以使用50多种方法来表达"。
- 原始内容:关系代数的运算符是通用的……运算符是"只读"的……在需要属性对应关系
时,Tutorial D认为所讨论的属性实际上就是一个属性……SQL是一个高度冗余的语言
……即使是"获得供应了P2型号零件的供应商名称"这样的简单查询也可以使用50多种
方法来表达。