使用 Null 来表示值是不好的做法吗?

Posted

技术标签:

【中文标题】使用 Null 来表示值是不好的做法吗?【英文标题】:Is using Null to represent a Value Bad Practice? 【发布时间】:2009-01-18 21:25:26 【问题描述】:

如果我使用 null 作为数据库表中所有内容的表示,那是一种不好的做法吗?

我有表格:myTable(ID) 和 myRelatedTable(ID,myTableID)

myRelatedTable.myTableID 是 myTable.ID 的 FK

我想要完成的是:如果 myRelatedTable.myTableID 为 null,那么我的业务逻辑会将其解释为链接到所有 myTable 行。

我想这样做的原因是因为在创建 myRelatedTable 行之后,我有未知数量的行可以插入到 myTable 中,并且 myRelatedTable 中的某些行需要引用 myTable 中的所有现有行。

【问题讨论】:

【参考方案1】:

我认为您可能同意使用数字 3 来表示 3 以外的值是不好的。

同样的道理,使用 NULL 来表示除了没有值之外的任何东西都是一个坏主意。

如果您不同意并将 NULL 用于其他目的,那么在您之后的维护程序员将不会感激。

【讨论】:

我并不是要与“维护程序员来找你”双关语,而是一个快乐的意外。 当然,记住这个:codinghorror.com/blog/archives/001137.html 谢谢,我会放弃这个空洞的想法,关于实现我所描述的关系的最佳方式有什么建议吗?【参考方案2】:

这不是一个好主意,因为这样您就根本无法在 SQL 查询中使用“与所有条目相关”这一事实。在某些时候,您可能想要/需要这样做。

【讨论】:

【参考方案3】:

理想情况下根本不应该有空值。应该有另一个表来表示关系。

如果您要分配特殊含义,但 NULL 应该只表示“未分配” - 即不存在关系,请使用负数,即 -1 如果您想触发一些业务层诡计。任何将来遇到此问题的开发人员都应该清楚,-1 是一个不寻常的值,不应被视为正常值。

【讨论】:

任何类型的幻数 (-1) 和/或业务逻辑技巧都是不好的。问题是,-1 代表一些特殊情况,但是你得到另一个特殊情况,所以你使用 -2,依此类推。然后你会得到几个神奇的数字。我现在正在维护一个发生这种情况的应用程序 - 太糟糕了。【参考方案4】:

我不认为 N​​ULL 是最好的方法,但您可以使用单独的 tinyInt 列来指示 MyRelatedTable 中的行与 MyTable 中的所有内容相关,例如MyRelatedTable.RelatedAll。这将使其他必须维护它的人更加明确。然后你可以做某种联合查询,例如

SELECT M.ID, R.ID AS RelatedTableID,....
FROM MyTable M INNER JOIN MyRelated Table R ON R.myTableId = M.Id
UNION
SELECT M.ID, R.ID AS RelatedTableID,....
FROM MyTable M, MyRelatedTable R
WHERE R.RelatedAll = 1

【讨论】:

【参考方案5】:

是的,原因很简单,NULL 代表没有价值。不是特殊值;不是空值,但什么都没有。

如果外键只是一个简单的整数,并且是自动生成的,那么你可以用 0 来表示“魔法”值。

【讨论】:

据我所知,0 会破坏 FK 约束【参考方案6】:

您发布的内容,即外键中的 NULL 断言与引用表中所有行的关系,是非常不标准的。在我的脑海中,我认为它充满了危险。

大多数在 FK 中使用 NULL 的人的意思是,它断言与引用表中的 NONE 行的关系。这在可选关系的情况下很常见,可能出现零次。

示例:我们有一个 HR 数据库,其中有一个名为“EMPLOYEES”的表。我们有两列,分别称为“EmpID”和“SupervisorID”。 (许多人将第一列简称为“ID”)。表中的每个员工在 SupervisorID 下都有一个条目,但公司的 CEO 除外。 CEO 在 SupervisorID 列中有一个 NULL,表示 CEO 没有主管。 CEO 对 BOD 负责,但在 SupervisorID 中没有体现。

与引用表中的所有行的关系可能是指:有问题的行与引用表中的任何行之间存在可能的关系。当您开始研究现实世界中真实但数据库未知的事实问题时,您会打开一大堆蠕虫。

【讨论】:

以上是关于使用 Null 来表示值是不好的做法吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用“is”来命名布尔变量是不好的做法吗?

使用无限while循环动态更改值是不好的做法吗?

doStuff 并返回布尔值是不好的做法吗?

arr[0] = arr[1] = C 中的值是不好的做法吗?

指针变量声明了后其默认值是啥呢,啥时候它的值才为“null”空呢?

表达的值本身是表达吗?