我应该在布尔型数据库字段中将False作为Null存储吗?


20

假设您有一个应用程序,该应用程序的表中有一个布尔字段,User称为Inactive

仅将false存储为null是否有天生的错误?如果可以,请您解释一下不利之处吗?几个月前,我已经与某人讨论了这一点,我们都同意,只要您在整个应用程序/数据库中始终如一地进行操作,就没有关系。最近,我认识的某个人强调应该使用“ true” true或“ true” false,但是他们并没有真正解释原因。


25
维基百科说 Null is a special marker used in Structured Query Language (SQL) to indicate that a data value does not exist in the database这是公认的智慧,您不应重新定义Null在您的应用程序中的含义。这会使使用您的代码的其他人感到困惑。
PersonalNexus

10
您为什么还要这样做?为什么不使用非空位字段并将默认值设置为false(如果这是您想要的行为),而不是将问题与三态字段混淆呢?
JohnFx 2012年

5
为什么这是一个非常糟糕的主意的真实示例: SELECT * FROM foo WHERE bar = FALSE没有给出您期望的结果。
Blrfl 2012年

2
考虑使用默认为0而不是布尔值的int列。这样,如果出现新情况(例如,可能处于“待定”状态),则不必更改数据库结构。
GrandmasterB'2

4
但是,如果将false存储为null,将如何存储FILE_NOT_FOUND?(thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
埃德詹姆斯

Answers:


50

仅将false存储为null是否有本质上的错误?

是。

如果可以,请您解释一下不利之处是什么?

NULL与False不同。

根据定义,涉及NULL的比较(和逻辑)应返回NULL值(不是False)。但是,SQL实现可能有所不同。

True and NULL 为NULL(不是False)。

True and NULL or False 为NULL(不是False)。

http://en.wikipedia.org/wiki/Null_(SQL)#Three-valued_logic_.283VL.29

http://technet.microsoft.com/zh-CN/library/cc966426.aspx


3
关于为什么NULL是表示缺少值的值的简要说明。
maple_shaft

2
我的第一份开发工作的第一天涉及调试和修复此类问题/答案中的错误,让人想起+1
tsundoku 2012年

1
请注意,您链接到的那篇文章说,如果null逻辑与逻辑无关(如whatever OR TRUE或的情况whatever AND FALSE,其中的值whatever不能更改条件),则表达式将返回一个值。这不是一种优化;这就是三值逻辑的工作原理。任何坚持为这些表达式返回UNKNOWN/的DBMS都将NULL被破坏。
cHao 2012年

1
@ S.Lott,但是不存储null而不是false可以节省一些空间?
azerafati 2014年

2
@Bludream:对于布尔值,可空字段实际上可以占用更多空间,具体取决于DBMS。(尽管在几乎所有情况下,这都是微不足道的数量。)布尔值可以用一个位表示...但是可空值的布尔值具有三个可能的值(true,false和null),因此需要多个位。
cHao 2014年

15

通过在布尔值字段中允许空值,您可以将预期的二进制表示形式(true / false)转换为三态表示形式(true,false,null),其中“ null”项是不确定的。“ null”值既不是适当的“ true”,也不是“ false”。您有什么理由要扩大您的表述的准确性呢?

即使您决定了这样的模式并在整个应用程序中始终如一地进行,那也不是一件容易的事。您最终会陷入无法清晰地知道为什么存在该模式的情况,或者更有可能最终会陷入那种模式被无意间破坏的情况。


5

别人怎么说。3个可能的值不是布尔值。

但是您可能有3个值的合法需求。如(真,假,未知)。即使是这种情况,如果您要进行超规范化,您将根本不允许任何空值。相反,您将在一个具有1到1关系的另一个表中存储一个真正的布尔值。空值可以在查询中通过“失败的”外部联接产生,而不是通过物理存储的空值产生。


在我的布尔值问题之外,如果您使用null来执行操作,为什么true false unknown会不好?除了我的问题之外,通常应避免使用null吗?为什么?
Ominus

3
@Ominus:如果您是纯粹主义者,通常应避免使用Null。如果按原样使用它们(因为“这里没有价值”,而不是伪造的伪造品false),那么它们就占有一席之地。如果它们不存在,它们将不存在。如前所述,替代方法基本上是拥有一个整个表,其中仅包含您行的主键和一个布尔值(或int或varchar或您拥有的内容)。对于否则将为空的每个字段。尽管关系纯净,但对于大多数目的而言却太复杂了。
cHao 2012年

-3

bool?布尔类型吗?不,它是类型的Nullable<T>地方T是布尔值。可为空的布尔值可以具有3个值:true,false和null。使用bool还是bool?取决于您的要求。出于合理的原因,您可能需要使用null,但是闻起来像二进制的类型,但您不知道答案。在以上示例中,User.IsActive似乎很明确。用户是否活跃。作为系统,它可能想知道用户是否处于活动状态。不应有“也许”。但是考虑一下功能标记之类的东西。该功能是否打开?答案可能是肯定,否定或不确定。您可能有一条业务规则,仅当flag设置为true时才拼写仅显示按钮。有人可能会说bool在默认情况下是false,那么为什么要创建可为null的bool?颠倒要求:您是否要将数据源中的所有值都设置为true?


2
这篇文章很难阅读(文字墙)。您介意将其编辑为更好的形状吗?
t
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.