知识卡片

数据库约束必须立即检查的理由与语义优化

普通读书笔记卡

内容

书中给出五条理由支持”约束必须在语句边界立即检查、不能延迟到事务提交”这一 立场。最重要的一条:数据库是真命题的集合([[类型与关系的逻辑区别数据库是 逻辑系统]]),一旦允许集合内部出现暂时的不一致,这个”真命题集合”的说法就 不再可信;后续[[约束与谓词逻辑正确与现实正确的分离及爆炸原理]]会证明,从 不一致的前提出发能推出任意结论。第二条理由动摇了”隔离性能兜底”的直觉:即使 事务隔离性保证某个不一致只在一个事务内部可见,只要TX1读到了这个不一致并 产生了错误结果,而这个结果又被TX2读取或某个局部变量传播给了外部使用者, 这个不一致实际上就已经”泄漏”出了事务边界——隔离性并不真正阻止这种间接传播。 第三条理由是正交性:不该强迫任何代码单元在被调用时还要操心”数据库当前是不是 处于事务中途的不一致状态”这种额外负担。第四条理由来自互换性原理:同一个约束 在一种数据库设计下可能是单关系变量约束(比如”伦敦供应商”和”非伦敦供应商” 分成两个基关系变量时,”两者供应商编号不重叠”这条约束天然隐含成立,不需要 显式声明),换一种设计(把两者做成视图、由并集构成的基关系变量S)却变成 了需要显式声明的多关系变量约束——同一件事仅仅因为设计选择不同就在”是否该 立即检查”上区别对待,逻辑上说不通。第五条理由是语义优化:只要约束在任何 时刻都成立(不仅仅是事务提交时),优化器才能放心利用它简化查询——书中举例 (SP JOIN S){PNO}因为外键约束保证SP的每一行都能在S中找到对应项,可以直接 简化成SP{PNO},省去整个连接;如果约束只在事务结束时保证成立,那么这类 基于约束的化简在事务执行过程中的任何一个中间时刻都可能是错误的,等于把 语义优化这条极具潜力的优化路径彻底堵死。

参考来源

- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第8章"SQL与约束" 8.6节"数据库约束为什么必须立即检查"(源文件:OEBPS/text00094.html) - 结论依据:原文明确"如果此集合允许包括不一致性,那么原先的说法就不能当真 了……如果允许不一致存在,那么无论如何也不能保证某个不一致只被一个事务 看到……互换性原理隐含说明了,一个约束可以既在某一个数据库设计中作为单 关系变量约束,又在另一个数据库设计中作为多关系变量约束……只有当某个完整 性约束发挥作用才有效的变换称为语义变换,其形成的优化称为语义优化……如果 一个约束在语义优化中是有用的,那么此约束就必须不仅在事务边界得到满足, 还要在……语句边界处都满足"。 - 原始内容:如果此集合允许包括不一致性,那么原先的说法就不能当真了……只有 当某个完整性约束发挥作用才有效的变换称为语义变换,其形成的优化称为语义 优化……如果一个约束在语义优化中是有用的,那么此约束就必须……在语句边界 处都满足。