将所有数据库列设置为NOT NULL是一种好习惯吗?

时间:2009-10-18 01:13:53

标签: database

通常将所有数据库列设置为NOT NULL是不错的做法?证明你的答案。

17 个答案:

答案 0 :(得分:36)

没有。在适当的情况下将列设置为NULL

是个好主意

答案 1 :(得分:31)

我有点不同意“适当的”规则。将任何列设置为NOT NULL实际上是相当安全;然后在需要时修改列以允许NULL值。另一方面,如果您先允许NULL值,然后再决定您不想允许它们,那么执行此操作可能会更加困难。

如果过度执行此操作,可能会使您的数据库表/列描述变得非常难看,但如果有疑问,请继续并限制数据。

答案 2 :(得分:11)

关系理论认为NULL是邪恶的。

但是,你的问题提到了实践。

因此,在某种程度上,你希望你的实践符合理论的天堂理想,是的,避免NULL好像是瘟疫,霍乱和艾滋病一体化。

如果这些称为“SQL DBMS”的糟糕实现不会给你任何其他选择,是的,(嗅探)使用它们。

修改

有人提到“业务规则”作为接受答案中“适当性”的指导原则,还有一些人赞成这句话。那是完全废话。业务规则总是没有NULL,而“适当性”的唯一指导是任何SQL系统的缺陷,使得它成为一个非关系系统来启动。

答案 3 :(得分:6)

NULL引用的发明者(1965)最近将其称为“十亿美元的错误”:http://qconlondon.com/london-2009/presentation/Null+References:+The+Billion+Dollar+Mistake

默认情况下,Scala,SML和Haskell等语言为非NULL:NULL称为“Option”或“Maybe”,需要特殊的语法和检查。

由于数据库的发明时间,默认情况下允许NULL被认为越来越危险和不可取。数据库应该遵循?可能。

尽可能使用NOT NULL。

答案 4 :(得分:5)

如果在插入时无法知道值,则必须允许空值。例如,假设您有一个包含两个字段的记录,即开始日期和结束日期。您知道插入记录时的开始日期,但不知道结束日期。为了避免空值而创建一个假日期放在这个字段中至少可以说是愚蠢。

在现实生活中,至少同样多的伤害是由于强迫数据进入某个领域而造成的。如果您有一个电子邮件字段并且不知道客户的电子邮件,那么用户必须做出一些事情才能进入必填字段。可能他们所构成的可能不是你希望他们构成像“thisistupid@ass.com”这样的东西。有时,这些不良信息会被提供回客户端或数据源中的供应商,而您的公司看起来真的很愚蠢。我知道,当我处理来自客户的大量这些Feed时。电子邮件领域的好东西包括,“他的秘书是肥胖的金发女郎”,“这家伙是一个混蛋”等。

答案 5 :(得分:4)

从我的角度来看,虽然数据库可能更好,但对用户来说并不是更好。一旦进入更多交互式应用程序,您希望能够将数据保持在临时状态,因此此时您的大多数字段可能都为空。

答案 6 :(得分:4)

我是新手,我的回答可能完全是讽刺的,但这是我对这个主题的个人看法。

在我看来,我没有看到允许除主键/外键之外的所有字段都可以为空的问题。我知道你们中的许多人在我这么说的时候就畏缩了,我确信我听到有人喊出来,“异教徒!把他烧死了!”但这是我的理由:

实际上数据库的工作是强制执行关于应该和不应该允许哪些值的规则 - 当然除非需要强制执行参照完整性和控制存储消耗(通过比如max chars set)?在将值存储在数据库中之前,在代码级别强制执行所有“null与非null”规则会不会更容易也更好?

毕竟,无论如何,在将所有值存储到数据库之前验证所有值是代码的工作,对吧?那么为什么数据库试图通过设置有关哪些值有效的规则来篡夺代码的权限呢? (在某种程度上,使用非null约束,除非绝对必要几乎感觉违反了“关注点分离”的想法。)此外,每当在数据库级别强制执行约束时,必须在代码中强制执行约束。级别还可以防止代码“爆炸”。那么为什么要做两倍的工作?

至少对我而言,当我的数据库被允许简单地成为“哑数据存储容器”时,似乎事情变得更好了,因为过去当我试图使用“NOT NULL”强制执行业务时不可避免地当时对我有意义的规则,我最终希望我没有,最后回去取消约束。

就像我说的那样,我意识到我是新手,如果有什么东西我会忽略,请告诉我 - 尽量不要把我弄得太糟糕了:)谢谢。

答案 7 :(得分:2)

这取决于您尝试做什么,但对于许多应用程序而言,尽可能避免NULL是一个好主意 - 最简单的方法是使用NOT NULL

问题是NULL的含义可以解释。它可能意味着“没有价值属于这里”,或者它可能意味着“我们还没有获得价值,所以我们应该不断向用户询问。”如果您正在使用它,您将要阅读SQL的3-valued logic以及COALESCE等函数。

尽管如此,正如Cletus和其他人所说,如果你恰当地使用NULL ,它会很有用。

答案 8 :(得分:2)

在商业应用程序中,我总是删除我的NOT NULLS,因为用户不喜欢被迫输入他们不知道的数据。它取决于表,但我将大部分字段设置为NULL,并且只将最小字段数设置为NOT NULL。

答案 9 :(得分:1)

如果您的数据实际上可能是“未知”,并且记录该事实很重要,那么请使用NULL。请记住,有时您需要区分“未知”和“不相关” - 例如,我的一个数据库中的DateTime字段可以是SQL Server最小日期(不适用),NULL(未知)或任何其他日期(已知值)。

对于那些根本不具备业务规则的字段 - 我在这里谈论“评论”,“描述”,“注释”列 - 然后我将它们设置为默认为空字符串,如(a)它可以节省处理空值,并且(b)它们永远不会“未知” - 它们只是没有填充,逻辑上是一个已知的空值。

E.g:

CREATE TABLE Computer (
  Id INT IDENTITY PRIMARY KEY
  , Name NVARCHAR(16) NOT NULL
  , ...[other fields]...
  , Comments NVARCHAR(255) NOT NULL
      CONSTRAINT DF_Computer_Comments DEFAULT (N'')
)

如果您没有为评论提供值,则默认为空。

答案 10 :(得分:0)

你不应该忘记在需要的地方设置非空,如果适用的话,使用检查约束,不要忘记独特的约束,创建适当的指数,并在每餐后和睡觉前刷牙:)

在大多数情况下,您可以使用not null,您应该使用not null。更改非null-> null比在相反方向更容易,但是例如在Oracle中,空字符串被视为null,因此显然您不能一直使用它。

答案 11 :(得分:0)

仅对没有值的列没有任何意义。

Nulls非常方便;一方面,它们压缩得很漂亮。但是,当你不指望它们时,它们可能是一个令人讨厌的惊喜,所以如果你没有一个没有名字的学生 - 让那个列不是NULL。 (中间名,另一方面......也许你想要一个默认的空字符串,也许不是 - 两种方式都是不错的论据)

答案 12 :(得分:0)

替代方案是什么?

我在工作中讨论了这个问题。我们的问题是:

我们是否应该拥有具有唯一约束的可空外键关联表 背景是有时存在关联,有时也没有关联。 (EG:计划外计划与计划时间表)

对我来说,可以为空的外键和一个'设置字段的组合在删除'相当于关联表,但有两个优点:

  1. 更易理解(架构已经很复杂)
  2. 更容易找到'无计划的'带有&x; xxx的时间表为空'查询(与不存在查询对比)
  3. 总结,有时' null' (缺乏信息)实际上意味着什么。尝试使用非null,但也有例外。

    FWIW,我们使用的是Scala / Squeryl,因此,在代码中,该字段是一个“选项”'非常安全。

答案 13 :(得分:0)

我的看法是,如果你想在某种程度上拥有灵活和“模糊”的表,只需使用NoSQL,因为它是为此目的而精确构建的。否则,在一行中有一个NULL值是可以接受的,因为它可能是一些可选数据,如地址2,或家庭电话号码等等。

在我看来,使外键可以为空是打破我们使用关系数据库的主要原因之一。您希望数据尽可能紧密相关且一致。

答案 14 :(得分:0)

简短回答:这取决于你要存储的内容。

我可以看到一张(或两张)所有NOT NULLS或全部NULLS的表格。但整个数据库?

答案 15 :(得分:0)

取决于(在数据类型上)

想一想,如果与数据库交互的直接技术是Python,我将使NOT NULL具有适当的DEFAULT

但是,如果列为VARCHAR且默认为空字符串,则上述内容才有意义。

NUMERIC如何,很难提出默认值,其中NULL可以传达更多细节,而不仅仅是设置为DEFAULT=0

BOOLEAN NULL仍有def checkType(a_list): for element in a_list: if isinstance(element, int): print("It's an Integer") if isinstance(element, str): print("It's an string") if isinstance(element, float): print("It's an floating number") numbers = [1, 2, 3] checkType(numbers) 有道理,等等。

可以对各种数据类型(如空间数据类型)执行类似的参数。

答案 16 :(得分:-2)

IMO,必须最小化使用NULLable选项。应用程序应为“不存在”状态指定合适的值。在Peoplesoft中我认为,应用程序为Numericals设置0,为Char列设置空格,其中值不存在。

有人可能会争论为什么所谓的合适值不能为NULL。

因为SQL实现完全不同地处理空值。

例如 1 = NULL和0 = NULL都导致错误! NULL = NULL为false! GROUP BY和其他聚合函数中的NULL值也会产生意外结果。