习惯上我们在应用系统中一直使用两值逻辑:非True即False。两值逻辑的运算体系已经相当成熟,与、或、非以及衍生的异或、与非等等。但是在实际应用中,我们会有机会遇到三值逻辑。
三值逻辑通常包含可选的True、False、NULL。如何在完备的两值逻辑运算体系中加入这个NULL,使之满足我们的需要,并且不会引发逻辑矛盾,就是我们要在这里讨论的。
NULL参与逻辑运算时,实际上存在着不同的算法。按NULL值在运算中的“优先级”分为三种。
通常我们在数据库中使用的三值逻辑,遵循NULL最优的原则。有NULL值参与二值运算时,返回结果为NULL,其它与二值逻辑相同。这一原则基于关系型数据库将NULL视为“未知”。由于其内容未知,则任何逻辑值与之进行运算的结果都是未知(无意义值),这也与许多数据关系型数据库对NULL的处理一致。
另一方面,可能有些朋友没有注意到,事实上常见的权限体系也是一种三值逻辑,这个体系里NULL值处于最低优先级,两个权限值进行合并时,False(否定)高于一切,没有否定值时,肯定值(True)高于NULL,只有两个值均为NULL时,结果才为NULL。实际上我们可以将它看作是一个三值与运算,那么出于数学上的对称,很容易可以构造出对应的逻辑或运算。这种运算规则视NULL为“未赋值”。
最后一种规定NULL值的优先级介于True和False之间,与运算,二者有一为False时,返回False,否则二者有一为NULL时,返回NULL,二者均为True时返回True;或运算,二者有一为True时返回True,否则二者有一为NULL时返回NULL,二者均为False时返回False。这等于分别承认True和False在或和与运算中的最高优先级。同样它也是基于NULL值为“未知”的理念。但是在这种规则下,对NULL值严格视为未知的True或False,而第一种规则则将其视为二值逻辑之外的一个独立存在。也有一些数据库的三值逻辑是基于这个体系的,MSDN中给出了一个基于此规则的DBBool示例(用C#实现),我们在后面的讨论中会基于该示例构造一个更为全面实用的三值逻辑类。
关于NULL值的学术讨论其实一直没有休止过,这期间还出现过四元逻辑等理论。实践也证明,“真实”世界中客观存在着不止一种三值逻辑体系。在实用中应当依据具体情况选择最适合的规则。