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