知识卡片

NULL违反信息原理及SQL自身3VL支持的内在缺陷

普通读书笔记卡

内容

除了[[NULL与三值逻辑逻辑正确与现实正确的分离]]中的经验性证明,书中还给出一条 更形式化的反对NULL的理由:根据定义NULL不是值,由此层层推出——一个”包含NULL的 类型”根本不是类型(因为类型的定义就是值的集合);一个”包含NULL的元组”根本不是 元组(因为按[[元组的精确定义与元组从不包含NULL的推论]]元组只能包含值);一个 “包含NULL的关系”根本不是关系(因为关系的主体是元组集合,而元组不能包含NULL); 最终归结为,NULL和重复行一样,从根本上违反了关系模型最基础的信息原理 (Information Principle)——一旦数据库里有NULL,严格说这个数据库谈的就已经 不再是关系模型了。除此之外,SQL自身对3VL的支持还存在内在的自相矛盾:SQL虽然 支持UNKNOWN关键字,但UNKNOWN并不像TRUE/FALSE一样是BOOLEAN类型的合法值——SQL 本质上仍然只是二值逻辑(BOOLEAN只有TRUE和FALSE两个值),”第三个真值”却错误地 借用NULL来表示,这带来一连串诡异后果:把UNKNOWN赋值给一个BOOLEAN变量B,实际 效果是把B设为NULL;此后比较B=UNKNOWN不会返回TRUE而是返回NULL(因为它逻辑 等价于B=NULL,而x=NULL这种写法本身在SQL里甚至不是合法语法)——即无论B到底 是不是UNKNOWN,这个比较结果都是”未知”,这直接违反了赋值原理(一个变量刚被 赋成某个值后,检验它是否等于那个值理应必然为真)。这个自相矛盾的支持方式本身 就是”NULL机制设计有问题”的又一佐证。

参考来源

- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第4章"不要重复,不要 null"4.4节"null有什么毛病"(源文件:OEBPS/text00046.html) - 结论依据:原文明确"根据定义null不是值。因此:一个包含null的'类型'不是类型 ……一个包含null的'元组'不是元组……一个包含null的'关系'不是关系……null(和 '重复'一样)违反了最为基础的关系原理,即信息原理""SQL使用2VL,其BOOLEAN 类型只包含两个值,TRUE和FALSE;'第三个真值'错误地由null表示……比较式B=UNKNOWN 不管B值是什么总是返回null……此情况违反了赋值原理"。 - 原始内容:根据定义null不是值。因此:一个包含null的'类型'不是类型……一个包含 null的'关系'不是关系……null(和"重复"一样)违反了最为基础的关系原理,即信息 原理……比较式B=UNKNOWN不管B值是什么总是返回null……此情况违反了赋值原理。