FALSE 和 TRUE 与 NULL 和 TRUE
FALSE and TRUE vs NULL and TRUE
我有类型为 BOOLEAN
的列
起初(在 INSERT
),值始终是 FALSE
,只有在可以将列更新为 TRUE
之后
所以问题是:将此列设为 NOT NULL DEFAULT FALSE
,或将此列设为 DEFAULT NULL
,然后更新为 TRUE
(如果那样也将反向更新,请将列设为 NULL
而不是 FALSE
值,所以在这种情况下,永远不会使用 FALSE
值 )
从性能和存储节省的角度来看,哪个选择会更好?
这对存储没有任何意义的影响。根据其他可为空的列,如果此列恰好将可为空的位图溢出到下一个字节,我们将最多讨论一个字节,但很可能它根本不会添加任何存储。
对于性能(以及程序员productivity/maintenance),这在很大程度上取决于您打算如何使用它。这里的信息远远不够,如果不邀请任何真正读过这个问题的人参加您的所有项目会议,也不可能获得足够的信息。
就个人而言,当我有一个默认为 false 的布尔列(无论您选择如何表示它)然后在某个时候变为 true 并且 保持 true,我喜欢为此值使用可为空的 DateTime 列,其中任何日期都表示该值为真,而 NULL 表示假。我的经验是,您几乎总是最终想知道值变为真的日期和时间。
举个例子,我在高等教育部门工作。在这项业务中发生的一件事是向学生发送经济援助奖励信。然后学生签名并 return 字母。已接受的奖项以后可能会被拒绝或取代,但这不会改变学生已签署这封信并接受该奖项的事实。法规要求我们将这些信件存档,但从数据库的角度来看,只要知道是否接受信件中的奖励这个布尔问题就足够了。很快就很明显,我们还需要知道何时接受奖项。因此,日期时间列用于该字段。
如果除非明确设置为 TRUE,否则要假设为 FALSE,则使用 NOT NULL DEFAULT FALSE
。它还取决于您如何使用此列。如果您只测试 where column = TRUE,那么不要认为它会很重要。关键是 NULL 不等于 FALSE。
假装 NULL 为 FALSE 的麻烦在于 NULL 既不是 FALSE 也不是 TRUE。
如果您在 table some_table
中有一个列 null_or_true
,您可以编写三个 SELECT 语句:
SELECT COUNT(*) FROM some_table;
SELECT COUNT(*) FROM some_table WHERE null_or_true;
SELECT COUNT(*) FROM some_table WHERE NOT null_or_true;
第一个获取总行数,比如30。第二个获取null_or_true
中值为TRUE的行数;这可能 return 15。第三个查询 returns 是 null_or_true
为 FALSE 的行数,但是如果您只在这些列中存储 NULL 而不是 FALSE,它将 return 0. 要计算其他 15 行,您必须在以下位置编写变体:
SELECT COUNT(*) FROM some_table WHERE null_or_true IS NULL;
这种违反直觉的行为意味着您会从人们那里得到错误的答案,他们可能会对您 table 中存储的数据感到困惑。
因此,您应该选择:
NOT NULL DEFAULT FALSE
另一条路迟早会导致疯狂。
我有类型为 BOOLEAN
起初(在 INSERT
),值始终是 FALSE
,只有在可以将列更新为 TRUE
所以问题是:将此列设为 NOT NULL DEFAULT FALSE
,或将此列设为 DEFAULT NULL
,然后更新为 TRUE
(如果那样也将反向更新,请将列设为 NULL
而不是 FALSE
值,所以在这种情况下,永远不会使用 FALSE
值 )
从性能和存储节省的角度来看,哪个选择会更好?
这对存储没有任何意义的影响。根据其他可为空的列,如果此列恰好将可为空的位图溢出到下一个字节,我们将最多讨论一个字节,但很可能它根本不会添加任何存储。
对于性能(以及程序员productivity/maintenance),这在很大程度上取决于您打算如何使用它。这里的信息远远不够,如果不邀请任何真正读过这个问题的人参加您的所有项目会议,也不可能获得足够的信息。
就个人而言,当我有一个默认为 false 的布尔列(无论您选择如何表示它)然后在某个时候变为 true 并且 保持 true,我喜欢为此值使用可为空的 DateTime 列,其中任何日期都表示该值为真,而 NULL 表示假。我的经验是,您几乎总是最终想知道值变为真的日期和时间。
举个例子,我在高等教育部门工作。在这项业务中发生的一件事是向学生发送经济援助奖励信。然后学生签名并 return 字母。已接受的奖项以后可能会被拒绝或取代,但这不会改变学生已签署这封信并接受该奖项的事实。法规要求我们将这些信件存档,但从数据库的角度来看,只要知道是否接受信件中的奖励这个布尔问题就足够了。很快就很明显,我们还需要知道何时接受奖项。因此,日期时间列用于该字段。
如果除非明确设置为 TRUE,否则要假设为 FALSE,则使用 NOT NULL DEFAULT FALSE
。它还取决于您如何使用此列。如果您只测试 where column = TRUE,那么不要认为它会很重要。关键是 NULL 不等于 FALSE。
假装 NULL 为 FALSE 的麻烦在于 NULL 既不是 FALSE 也不是 TRUE。
如果您在 table some_table
中有一个列 null_or_true
,您可以编写三个 SELECT 语句:
SELECT COUNT(*) FROM some_table;
SELECT COUNT(*) FROM some_table WHERE null_or_true;
SELECT COUNT(*) FROM some_table WHERE NOT null_or_true;
第一个获取总行数,比如30。第二个获取null_or_true
中值为TRUE的行数;这可能 return 15。第三个查询 returns 是 null_or_true
为 FALSE 的行数,但是如果您只在这些列中存储 NULL 而不是 FALSE,它将 return 0. 要计算其他 15 行,您必须在以下位置编写变体:
SELECT COUNT(*) FROM some_table WHERE null_or_true IS NULL;
这种违反直觉的行为意味着您会从人们那里得到错误的答案,他们可能会对您 table 中存储的数据感到困惑。
因此,您应该选择:
NOT NULL DEFAULT FALSE
另一条路迟早会导致疯狂。