本节书摘来自异步社区出版社《你不可不知的关系数据库理论》一书中的第14章,第14.2节,作者:【美】C.J.Date,更多章节内容可以访问云栖社区“异步社区”公众号查看。
14.2 SQL与关系模型的不同点
此部分列出了SQL与关系模型的不同点,主要是为了参考,同时顺便进行一些附加说明。我知道可能会有人对列表中的个别术语吹毛求疵,一一解释列表中这些特性是非常不容易的,特别是它的正交性(例如,保证这些特性都相互独立,互不影响)。但是我认为这些吹毛求疵都不是重要的,重要的是它们累积起来造成的影响,坦率地说是相当惊人的3。
不再啰嗦了,下面具体来看一下它们的不同点:
SQL不能够完全区分表的值和表变量。
SQL表与关系(或关系变量)不同,因为它们不允许或不需要(根据具体情况而定):(a)重复的行;(b)空值;(c)从左到右有序排列的列;(d)无名的列;(e)重复的列名;(f)指针(虽然标准中没有,但至少在某种产品中存在);(g)隐藏的列。注意:(a)、(b)、(c)、(f)都代表破坏了信息准则。(d)和(e)(即无名的列和重复的列名)可能发生在评价某个表达式后得到的结果表中,不能出现在基表或者视图中。因此严格说来,如果我们遵守信息准则的规定(参见第7章),那么(d)和(e)的情况就不会破坏它,因为这样的表就不会出现在数据库中。但奇怪的是,SQL允许我们可以得到不直接存回到数据库基表中的结果。因此,我认为(d)和(e)肯定会破坏信息准则(你可能不会相信)。
SQL没有恰当的表标识符。最接近于这种结构的表示方式是VALUES表达式(顺便说一下,处于某种特定的目的,批准或者篡改是经常使用的术语),这样的表达式就不能用在必须使用标识符的环境中。(对此,可以参见本章练习14.2。)
SQL通常认为视图不是表。下面这段文字摘自SQL and Relational Theory,但稍微进行了修改:
SQL标准,以及其他大多数的SQL文档通常都讨论了术语“表和视图”(事实上,是相当普遍的)。显然,采用此种方式讨论的人受到了“表和视图不同”的影响,认为“表”就是基本表,基本表是物理存储的,而视图不是物理存储的。但总的来说,视图就是表(或者我更愿意把它称为关系变量)。也就是说,对规则的关系变量(至少是关系模型)执行的运算,在视图上都可以执行,因为视图就是“规则的关系变量。”
从数学的角度来说,子集就是集合。实际上,基于集合理论的操作结果得到的就是集合。这个观点同样适用于关系模型,任何关系型表达式的操作结果就是关系,特别是对于定义视图的表达式也是如此。因此,认为SQL中的视图不同于表的那些人是没有从关系的角度考虑问题,这有可能会引发一些错误。
SQL表(从前面的叙述来看,要包括视图!)至少包含1列。对于该点的解释,请参照附录B(这里也说明了SQL不完全是关系型的)。
SQL没有显式的表赋值运算符。
SQL当然也没有显式的多变量表赋值运算(也没有类似的INSERT/DELETE/UPDATE操作)。
SQL在很多方面都破坏了赋值规则(The Assignment Principle),有一些是处理空值的(有一些是处理字符串类型的,还有一些是处理“可能的没有确定值的”表达式)。
SQL在很多方面都破坏了黄金规则(The Golden Rule),其中包括处理空值的,特别是推迟进行完整性检测方面。
SQL没有合适的“表类型”定义。
SQL没有表之间的“=”运算,实际上,它根本不执行表之间的比较运算。
SQL允许把合适的超码显式声明为码。
SQL的并、交、联接运算不满足交换律。
SQL的并、交、联接运算不满足等幂性。
SQL的并运算不是联接运算的特例(重复值和空值的存在是罪魁祸首)。
SQL中没有明确定义联接运算(原因是SQL表的内容是一组行的包,而不是集合)。
SQL没有适当的聚集运算符。
SQL在处理空集时会产生各种逻辑错误,包括语法和语义方面的逻辑错误。
很多SQL表的表达式都是“可能具有未确定值的”。
SQL支持各种行级的运算符(如游标的修改、行级的触发器等)。
虽然在SQL的标准中没有提供,但是某种特定的商业产品中使用的SQL专业术语有时确实会涉及物理级的构成(例如,索引)。
SQL的视图定义中包括映射信息以及结构化信息4。>{注意:}针对该点及下一点重要性的详细讨论可参见我的一本专著:View Updating and Relational Theory: Solving the View Update Problem(2013年,O’Reilly出版)。
SQL对于视图修改的支持是很薄弱的、针对特定问题的、不完整的。
SQL不能正确区分类型与描述之间的关系。(这个问题主要发生在SQL的子类型机制中,但不排除其他情况,详细讨论已经超出本书的范围。)
SQL不支持类型约束。
SQL的“结构化类型”有时被封装起来,有时却未被封装。>{注意:}结构化类型是SQL用来自定义类型的一种机制。详细讨论也超出本书的范围。
SQL不能正确区分类型和类型发生器。
虽然SQL标准中支持BOOLEAN类型,但大多数商业化产品却不支持该类型。
SQL对于“=”的支持是存在严重缺陷的。具体来讲,“=”可以(a)比较的两个数明显不同,但也可以得到TRUE;(b)两个比较的数没有明显差异,却不能得到TRUE;(c)因此可以用户自定义,所以在语义上存在二义性(特别是用户自定义类型中);(d)根本不支持定义XML类型;(e)虽然在标准中没有说明,但在一些特定的产品中也不支持一些特定的类型(如BLOB和CLOB)。
SQL是基于3-值逻辑的(可以这样说),但关系模型是基于2-值逻辑的。
如前所述,SQL不完全是关系型的。
SQL不直接支持映像关系,也不支持RENAME、XUNION(排他型并运算)、MATCHING、NOT MATCHING、D_UNION、I_MINUS、D_INSERT、I_DELETE。还有其他的未在本书讨论的关系运算符。
上述列出的条目并不详尽。