代码之家  ›  专栏  ›  技术社区  ›  Clay

将所有数据库列设置为非空是一个好的实践吗?

  •  21
  • Clay  · 技术社区  · 6 年前

    通常,将所有数据库列设置为非空或非空是一种良好的做法吗?证明你的回答是正确的。

    17 回复  |  直到 7 年前
        1
  •  36
  •   cletus    15 年前

    不,最好将列设置为空 在适当的情况下 .

        2
  •  31
  •   Fragsworth    15 年前

    我有点不同意“在适当的地方”规则。事实上 相当安全 将任何列设置为非空;然后在需要时修改列以允许空值。另一方面,如果您先允许空值,然后决定不允许空值,那么这样做可能会更加困难。

    如果这样做过多,可能会使数据库的表/列描述变得很难看,但如果有疑问,请继续并限制数据。

        3
  •  11
  •   Erwin Smout    10 年前

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

    不过,你的问题有点涉及实践。

    所以,如果你希望你的实践符合天堂的理论理想,是的,避免 无效的 就好像瘟疫、霍乱和艾滋病是一体的。

    在某种程度上,这些称为“SQL DBMS”的蹩脚实现不会给您留下任何其他选择,是的,(嗅探)使用它们。

    编辑

    有人在接受的答案中提到“商业规则”作为“适当性”的指导方针,还有一些人反对这句话。那完全是废话。商业规则总是可以做到没有 无效的 而“适当性”的唯一准则是任何SQL系统的缺陷,使其成为一个非关系系统来引导。

        4
  •  6
  •   Adam Goode    15 年前

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

    scala、sml和haskell等语言在默认情况下是非空的:空被称为“选项”或“可能”,需要特殊的语法和检查。

    自从数据库被发明以来,默认情况下允许空值被认为是越来越危险和不可取的。数据库应该遵循吗?可能。

    如果可以,请使用不为空。

        5
  •  5
  •   HLGEM    15 年前

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

    在现实生活中,强制数据输入字段所造成的危害至少与不强制数据输入字段所造成的危害相同。如果你有一个电子邮件字段,并且不知道客户的电子邮件,那么用户就必须编一些东西来放入所需的字段中。很可能他们组成的不是你希望他们组成的“thisistupid@ass.com”。有时,这些坏信息会被提供给客户或数据馈送中的供应商,而您的公司看起来真的很愚蠢。我知道我处理了很多来自我们客户的反馈。电子邮件领域的好东西包括:“他的秘书是个胖金发女郎”,“这个家伙是个混蛋”等等。

        6
  •  4
  •   Josh    15 年前

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

        7
  •  4
  •   dhughes    7 年前

    我是个新手,我的回答可能完全愚蠢,但这是我对这个问题的个人看法。

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

    这真的是 数据库 执行关于哪些值应该和不应该被允许的规则-当然,除了需要强制执行诸如引用完整性之类的东西和控制存储消耗(通过设置max chars之类的东西)?在 代码 在数据库中存储值之前的级别?

    毕竟,在将所有值存储到数据库之前,验证它们是代码的工作,对吗?那么,为什么数据库还要通过设置关于哪些值有效的规则来试图篡夺代码的权威呢?(在某种程度上,除了绝对必要的情况外,使用非空约束几乎感觉违反了“分离关注点”的概念。)此外,任何时候在数据库级别强制执行约束时,都必须在代码级别强制执行约束,以防止代码“爆炸”。那么,为什么要执行两倍的工作呢?

    至少对我来说,当我的数据库被允许仅仅是一个“愚蠢的数据存储容器”时,事情似乎会变得更好,因为在过去,当我试图使用“非空”来强制执行当时对我有意义的业务规则时,不可避免地,我最终希望自己没有这样做,最终返回并删除约束。

    就像我说的,我意识到我是一个新手,如果有什么我忽略了的,告诉我——尽量不要把我宰得太厉害:)谢谢。

        8
  •  2
  •   David    15 年前

    这取决于你想做什么,但对于许多应用来说,最好避免 NULL 在可能的情况下-最简单的方法是使用 NOT NULL .

    问题是 无效的 易于解释。可能意味着” 此处不属于任何值 “或者可能意味着” 我们还没有得到这个值,所以我们应该继续向用户索要它。 “如果您正在使用它,您将希望阅读SQL的 3-valued logic 以及诸如 COALESCE 等。

    然而,正如克莱特斯和其他人所说,如果你使用 无效的 适当地 它可能很有用。

        9
  •  2
  •   DJ.    15 年前

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

        10
  •  1
  •   Keith Williams    15 年前

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

    对于没有业务规则依赖的字段-我在这里讨论“注释”、“描述”、“注释”列-然后我将它们设置为默认为空字符串,因为(a)它保存了处理空值的过程,以及(b)它们从不“未知”-它们只是没有填充,逻辑上是一个已知的空值。

    例如。:

    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'')
    )
    

    如果不为注释提供值,则默认为空。

        11
  •  0
  •   Kris Krause    15 年前

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

    我可以看到一个表(或两个表)具有所有非空值或所有空值。但是整个数据库呢?

        12
  •  0
  •   SquareCog    15 年前

    仅适用于没有值的列。

    空可以非常方便;一方面,它们压缩得很好。但是,当你不期望他们出现时,他们可能会是一个令人讨厌的惊喜,所以如果你不能让一个没有名字的学生出现,那就让这个列不为空。(中间名,另一方面…也许你想要一个默认的空字符串,也许不是——两边都有合适的参数)

        13
  •  0
  •   LukLed    15 年前

    您不应忘记在需要时设置不为空,如果适用,请使用检查约束,不要忘记独特的约束,创建适当的索引,并在每次饭后和睡前刷牙:)

    在大多数情况下,您可以使用非空值,并且应该使用非空值。与相反方向相比,更容易更改不为空->空,但在Oracle中,空字符串被视为空,因此很明显您不能一直使用它。

        14
  •  0
  •   Peter L    11 年前

    还有什么选择?

    我发现这个问题是工作中讨论的结果。我们的问题是:

    我们应该有一个 可以为空的外键 关联表 有独特的约束吗? 背景是有时有关联,有时没有关联。(例如:计划外与计划外的时间表)

    对于我来说,可以为空的外键与“set field to null on delete”的组合等价于关联表,但有两个优点:

    1. 更容易理解(模式已经很复杂)
    2. 使用“xxx is空”查询更容易找到“未计划”计划(而不是不存在的查询)

    综上所述 有时“空”(缺少信息)实际上意味着什么。尝试使用非空值,但有例外。

    fwiw,我们使用scala/squeryl,所以在代码中,字段是一个“选项”,非常安全。

        15
  •  0
  •   Henry Ollarves    8 年前

    我的看法是,如果您希望在某种程度上拥有灵活和“不明确”的表,那么只需使用nosql,因为它正是为此目的而构建的。否则,行中有一个空值是可以接受的,因为它可能是一些可选数据,比如地址2、家庭电话号码等等。

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

        16
  •  0
  •   nehemiah    7 年前

    它取决于 (在数据类型上)

    考虑一下,如果与数据库交互的直接技术是python,那么我将使一切 NOT NULL 用适当的 DEFAULT .

    但是,如果列是 VARCHAR 默认为空字符串。

    怎么样 NUMERIC ,很难找到默认值,其中 NULL 可以传达更多的细节,而不是简单地设置为 DEFAULT=0

    为了 BOOLEAN 仍然 无效的 有点道理,等等。

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

        17
  •  -2
  •   srini.venigalla    15 年前

    IMO,使用可空选项必须最小化。应用程序应为“不存在”状态指定适当的值。我认为,在PeopleSoft中,应用程序将数值设为0,将值不存在的字符列设为空格。

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

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

    例如 1=空和0=空都会导致错误! 空=空为假! group by和其他聚合函数中的空值也会产生意外的结果。