知识卡片

除运算符的局限性:为什么应被映像关系取代

普通读书笔记卡

内容

除(DIVIDE)是本章唯一一个作者明确建议”读者完全可以忽略”、甚至”应该抛弃”的 运算符,理由有三:其一,任何能写成除形式的查询都可以用[[映像关系的精确定义 与双感叹号运算符]]更简单地表达;其二,”除”这个名字下实际有7个以上不同定义的 运算符版本;其三,最根本的问题是——除运算符甚至没有正确解决它本该解决的问题。 最基础版本的除定义为:r1 DIVIDEBY r2r1{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个! ……这个表达式实际上表述的是查询'得到至少提供了一种零件,并且实际上提供了 所有零件种类的供应商的供应商编号'……除运算符不仅受复杂性及繁复性的制约, 甚至还没有解决它本来应该解决并且明确要解决的问题"。 - 原始内容:我认为"除"并不重要……甚至觉得应该抛弃除……除运算符不仅受复杂性 及繁复性的制约,甚至还没有解决它本来应该解决并且明确要解决的问题。