知识卡片

关系赋值统一INSERT/DELETE/UPDATE与赋值原理

普通读书笔记卡

内容

[[关系值与关系变量的区分及DELETE的本质]]中已提到DELETE本质是关系赋值的简写, 本节把这个等价关系系统化地展开到INSERT:INSERT R rx;定义为R := R UNION rx;的简写;DELETE R WHERE bx;R := R WHERE NOT(bx);(等价于R := R MINUS(R WHERE bx))的简写。这个等价关系有一个容易被忽视的语义后果:既然 INSERT本质是并运算,插入一条已经存在的元组不会报错,只是并运算”吸收”了这个 重复、什么都不会发生;如果确实需要”插入必须是全新元组,重复则报错”这种更严格 的语义,Tutorial D专门提供了D_INSERT(不相交INSERT,底层用D_UNION实现,要求 两侧运算元不能有相同元组);对称地,普通DELETE允许”删除不存在的元组”(同样 什么都不会发生),若要求”待删除的元组必须先存在,否则报错”则要用I_DELETE (底层用I_MINUS,即包含差实现)。SQL在INSERT/DELETE/UPDATE上和Tutorial D的 关键区别在于:SQL的INSERT语义上更接近UNION ALL而非UNION,因此在没有键约束 的表里插入重复行是允许的;SQL完全没有真正意义上的关系赋值运算符,最接近的 写法是先DELETE FROM T;INSERT INTO T(...) tx;两条语句的序列,但这个 序列可能会失败(比如表T有NOT NULL约束、tx里某行违反约束),而理论上对应的 单次关系赋值本应直接成功或直接失败,不会出现”先删干净、再插入失败、表变空了” 这种中间状态。本节末尾提出的赋值原理(Assignment Principle)是所有赋值运算 (不限于关系赋值,是计算领域的通用原则)必须满足的底线:把值v赋给变量V之后, 比较式v=V必须返回TRUE——[[NULL违反信息原理及SQL自身3VL支持的内在缺陷]]中 B=UNKNOWN总是返回null的诡异行为,正是SQL自己违反这条基本原理的一个具体例证。

参考来源

- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第5章"基关系变量和 基表"5.2节"关系赋值"(源文件:OEBPS/text00053.html) - 结论依据:原文明确"INSERT R rx;……是如下运算的简写:R := R UNION rx;…… Tutorial D额外支持运算符D_INSERT……SQL中没有关系赋值运算符的直接对应物。 SQL与……最接近的情况是下面的语句序列:DELETE FROM T; INSERT INTO T (...)tx;……此语句序列可能会失败,而与其对应的关系操作(即关系赋值)则会 成功……在将值v赋给变量V后,比较式v=V必须返回TRUE。此准则的延伸就是赋值 原理"。 - 原始内容:INSERT R rx;是如下运算的简写:R := R UNION rx;……SQL中没有关系 赋值运算符的直接对应物……此语句序列可能会失败,而与其对应的关系操作(即 关系赋值)则会成功……在将值v赋给变量V后,比较式v=V必须返回TRUE。