知识卡片
更新是集合级别的运算
内容
关系模型里所有更新运算(本质上是所有关系赋值)都是集合级别的:运算元始终是
整个关系或整个关系变量,而不是单个元组——INSERT本质是向目标关系变量插入一个
元组集合,DELETE是删除一个元组集合,UPDATE是更新一个元组集合,日常所说的
“更新单条记录”只是恰好这个集合的基数为1的特例。更严格地讲,元组本身是值,
按定义不可更新([[关系值与关系变量的区分及DELETE的本质]]中已说明),”把关系
变量R中的元组t1更新为t2”这种说法本身是不严谨的,精确说法应该是”用另一个关系
r2整体替换R原本的值r1”,其中r2等于(r1 MINUS s1) UNION s2(s1、s2分别是只
含t1、t2的单元素关系)。这条”集合级别”原则还有一个不能被单条记录更新代替的
硬约束:书中给出反例,如果供应商S1和S4必须始终位于同一城市这条完整性约束
成立,那么任何试图只改其中一个供应商城市的”单元组UPDATE”必然违反约束而失败,
必须同时对两者做一次集合级更新才能成功;这直接说明SQL基于游标的”定位更新”
(UPDATE/DELETE WHERE CURRENT OF cursor)在语义上和关系模型的行级触发操作
一样,都不能替代真正的集合级更新——它们目前”能用”往往只是因为具体产品对完整性
约束的支持还不够严格,一旦产品加强约束检查,这类基于游标或行级触发器的更新
代码就可能突然失败。这条原则也解释了为什么完整性约束和触发操作只能在整个显式
请求的更新(可能是一批元组)全部完成之后才被检查——集合级更新不能被当成”若干
行级更新的序列”来处理,所有关系模型的运算都是”语义原子的”,要么整体生效,要么
(除返回状态码外)完全没有效果。
参考来源
- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第5章"基关系变量和
基表"5.1节"更新是集合级别的"(源文件:OEBPS/text00052.html)
- 结论依据:原文明确"不管用什么语法表达关系赋值,它都是集合级别的运算……关系
模型中没有什么东西对应于SQL的'定位更新'……'更新是集合级别的'这一事实还有另一
层意思:完整性约束在所有的更新……完成之前也是不能进行检查的……本节讨论的所有
关系模型中的更新运算……都是'语义原子的'"。
- 原始内容:不管用什么语法表达关系赋值,它都是集合级别的运算……完整性约束在
所有的更新(也包括触发操作,如果有的话)完成之前也是不能进行检查的……本节
讨论的所有关系模型中的更新运算(实际上是所有的运算)都是"语义原子的"。