知识卡片
除运算符的局限性:为什么应被映像关系取代
内容
除(DIVIDE)是本章唯一一个作者明确建议”读者完全可以忽略”、甚至”应该抛弃”的
运算符,理由有三:其一,任何能写成除形式的查询都可以用[[映像关系的精确定义
与双感叹号运算符]]更简单地表达;其二,”除”这个名字下实际有7个以上不同定义的
运算符版本;其三,最根本的问题是——除运算符甚至没有正确解决它本该解决的问题。
最基础版本的除定义为:r1 DIVIDEBY r2是r1{X} NOT MATCHING((r1{X} JOIN r2)
NOT MATCHING r1)的缩写(利用了半差),比如SP{SNO,PNO} DIVIDEBY P{PNO}常被
不严谨地说成是”获得提供所有零件型号的供应商”,因为除法在直觉上是积的逆运算
(r1 TIMES r2除以r2重新得到r1,前提是r2非空)。但书中揭穿了这个说法的不
精确之处:这个表达式实际返回的是”至少提供了一种零件、并且确实提供了全部零件
种类的供应商”,而不是字面意义上”提供所有零件型号”——具体反例是”提供了所有
紫色零件型号的供应商”这个查询:如果数据库里根本没有紫色零件,那么每个供应商
(包括S5这种完全没有任何出货记录的供应商)在逻辑上都”满足”这个条件,但除运算
表达式却不会把S5包含进结果,因为S5根本不出现在SP{SNO,PNO}里。相比之下,等价的
映像关系表达式S WHERE(!!SP){PNO}=P{PNO}不仅写法更简洁直观、语义也真正正确,
这正是[[哪些运算符是基本的基本与有用的区别]]的一个反面案例——除运算符不是
基本运算符,本身又存在语义缺陷,属于”既不基本、又不完全可靠”的运算符,取代它
的实用价值有限。
参考来源
- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第7章"SQL和关系代数
II:附加运算符"7.5节"除"(源文件:OEBPS/text00078.html)
- 结论依据:原文明确"我认为'除'并不重要……甚至觉得应该抛弃除……任何可写成除
形式的查询都可以以映像关系形式更简单地给出……除运算符太多了,至少有7个!
……这个表达式实际上表述的是查询'得到至少提供了一种零件,并且实际上提供了
所有零件种类的供应商的供应商编号'……除运算符不仅受复杂性及繁复性的制约,
甚至还没有解决它本来应该解决并且明确要解决的问题"。
- 原始内容:我认为"除"并不重要……甚至觉得应该抛弃除……除运算符不仅受复杂性
及繁复性的制约,甚至还没有解决它本来应该解决并且明确要解决的问题。