知识卡片

更新是集合级别的运算

普通读书笔记卡

内容

关系模型里所有更新运算(本质上是所有关系赋值)都是集合级别的:运算元始终是 整个关系或整个关系变量,而不是单个元组——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的'定位更新'……'更新是集合级别的'这一事实还有另一 层意思:完整性约束在所有的更新……完成之前也是不能进行检查的……本节讨论的所有 关系模型中的更新运算……都是'语义原子的'"。 - 原始内容:不管用什么语法表达关系赋值,它都是集合级别的运算……完整性约束在 所有的更新(也包括触发操作,如果有的话)完成之前也是不能进行检查的……本节 讨论的所有关系模型中的更新运算(实际上是所有的运算)都是"语义原子的"。