我应该使用NULL还是空字符串来表示表列中没有数据?

时间:2008-10-03 17:21:13

标签: mysql database null

空字符串或空字符串 - 是否比另一个更好,表示表格列中没有数据? (我特意使用MySQL,但我认为这是独立于系统的。)使用一个优于另一个是否存在主要优点/缺点,还是仅仅是程序员偏好?

16 个答案:

答案 0 :(得分:31)

我强烈反对所有无条件使用NULL的人。如果将列设置为NOT NULL,则允许列为NULL会引入一个额外的状态。如果您不需要其他状态,请不要这样做。也就是说,如果你无法想出空字符串的含义和null的含义之间的区别,那么将列设置为NOT NULL并使用空字符串表示空。用两种不同的方式表示同样的事情是一个坏主意。

大多数告诉你使用NULL的人也给出了一个例子,其中NULL意味着与空字符串不同。在这些例子中,他们是对的。

然而,大多数情况下,NULL是一种不必要的额外状态,只会迫使程序员处理更多情况。正如其他人所提到的,Oracle不允许存在这种额外的状态,因为它将NULL和空字符串视为同一个事物(在Oracle中不允许null的列中存储空字符串是不可能的。)

答案 1 :(得分:25)

空。空字符串不是“无数据”,它的数据恰好是空的。

答案 2 :(得分:4)

Null更好“”实际上代表数据,它不会在你的代码中注册相同

答案 3 :(得分:4)

在关系数据库模型的上下文中,null表示“无值”或“未知值”。它的存在完全是您描述的目的。

更新:对不起,我忘了添加,虽然大多数(所有?)RDMBS对null使用相同的定义,但处理null的方式存在细微差别。例如,MySQL和Oracle在UNIQUE列(或列集)中允许多个空值,因为null不是值,并且不能被视为唯一(null!= null)。但是我上次使用MS SQL Server时,它只允许一个null。因此,您可能需要考虑RDBMS行为,以及相关列是否会受到约束或索引。

答案 4 :(得分:4)

都不是。由于关系中没有元组,表示没有数据。

出于性能原因,您可能希望避免某些RDBMS中的连接,但尝试设计模型,以便可以丢失的信息处于单独的关系中。

答案 5 :(得分:3)

以下是MySQL网站的几个链接:

http://dev.mysql.com/doc/refman/5.0/en/problems-with-null.html

http://dev.mysql.com/doc/refman/5.0/en/working-with-null.html

我读了一次,NULL值是2位,其中空字符串只有1位。 99%的时间这没有任何区别,但是如果NULL''无关紧要,那么在一个非常大的表格中,使用''可能会更好如果这是真的。

答案 6 :(得分:3)

始终使用NULL。考虑“我不知道这个人的电话号码是什么”(NULL)和“此人留空”(空白)之间的区别。

答案 7 :(得分:3)

使用正确的工具完成工作。 NULL可以表示尚未提供任何值,或者它可以表示没有值适用。

但是空字符串也是信息。它可以表示某个值是适用的,并且已经给出,但它恰好是一个空字符串。

允许列包含NULL和''使您有机会区分这些情况。无论如何,使用一个来表示另一个是不好的。

请注意,在字符串连接中,任何与NULL结合的内容都会产生NULL。例如:CONCAT(NULL,'foo')产生NULL。如果要将NULL转换为SQL表达式中的某个默认值,请学习使用COALESCE()函数。

答案 8 :(得分:2)

大多数时候null更好。可能在某些情况下它几乎没有什么区别,但它们很少。请记住,当您查询field = ''field is null不同时(至少在MySQL中)。

答案 9 :(得分:1)

据我所知,Oracle没有区分差异。

select 1 from (select '' as col  from dual) where col is null;

答案 10 :(得分:1)

考虑为什么列中没有数据。这是否意味着桌面设计很草率?尽管不喜欢空值,但有时候它们是合适的(或者足够合适),并且系统通常不会死亡。永远不要在任何候选键(主键或替代键)中允许空值。

答案 11 :(得分:1)

为只有可为空的列和主表的外键创建一个单独的表。如果记录没有该列的数据,那么它将不会在第二个表中有记录。这是最干净的解决方案,您不必担心处理空值或为空字符串赋予特殊含义。

答案 12 :(得分:1)

NULL是一个非值,应该降级到它出现的黑暗时代。我发现处理特殊的NULL情况需要一些非常简单的编程,可以使用默认值轻松处理。

将列的默认值设置为空字符串。 强制列不允许null,一旦分配默认值,很可能永远不会发生。 快乐地编写代码,忽略列值为空的情况。

我一直使用NULL的一个大问题是“SELECT * from tbl WHERE column = NULL”将始终返回空结果集。 NULL永远不能等于任何东西,包括NULL。特殊关键字“column is null”是检查null的唯一方法。如果你退出null,那么比较将成功:“column =''”返回7行。

我从头开始做了两个主要的数据库实现,最后我后悔使用了NULL。下次,我没有NULL!

答案 13 :(得分:0)

有一个重要的例外。 Bill Karwin表示“CONCAT(NULL,'foo')产生NULL”,这对于大多数RDBMS都是如此,但对于Oracle来说则不然。

正如上面的James Curran所建议的,Oracle选择了这个相当关键的关键点,即通过将NULL和空字符串完全相同来脱离标准SQL。然而,比仅仅处理它们更糟糕的是,它实际上可能通过在连接时返回除NULL之外的其他内容来破坏NULL值的含义。

具体来说,在oracle CONCAT(NULL,'foo')中产生'foo'。感谢Oracle,我现在已经丢失了我的空值,这对您来说无关紧要,但是当数据传递给其他RDBMS进行进一步处理时,确实会有所不同。

答案 14 :(得分:0)

列中的“无数据”值应由默认值表示。请记住,NULL表示未知值,也就是说,列可以具有值,但是您此时不知道它。

例如,在贷款申请系统中,“驾驶执照号码”字段上的NULL值表示申请人或贷款处理者未输入驾驶执照号码。 NULL值并不自动意味着申请人没有许可证。他可能有也可能没有许可证,你只是不知道,这就是为什么它是NULL。

歧义在于字符串列。如果没有值,数字列显然包含零。你怎么能代表一个无价值的字符串?在上面的示例中,对于没有驾驶执照的申请人,您可以指定任意默认值,例如“none”或更好的空字符串。只需确保使用其他表中的默认空值即可。

关于不使用NULL作为原则的问题,有些情况下它们实际上是必不可少的。作为广泛使用统计数据的人,数据提供者通常会为您提供包含不完整数据的数据集。例如,在每个国家的GDP数据集中,您可以发现早期和晚年的GDP数据缺失。一个原因是该国政府没有这些年的官方数据。得出结论他们的GDP为零(DUH!)并且在提取的数据或图表中显示零值是不正确的。正确的值为NULL,这意味着您还没有数据。最终用户正确地将提取的数据和图形中缺失的数据点解释为非零。此外,它不会导致计算错误,尤其是在进行平均值时。

理论上有意义的一些“规则”实际上在你的案例中是一个糟糕或不正确的解决方案。

答案 15 :(得分:0)

我发现NULL值有助于参照完整性。对于MySQL,如果字段设置为NOT NULL,则插入需要设置数据;否则,NULL是一个可能的值,并且不强制执行外键约束。

  1. id:主键
  2. product_id:FOREIGN KEY NOT NULL
  3. ref_id :( NULLABLE)
  4. 始终需要

    id和product_id区域。 ref_id可以设置为NULL。但是,如果使用任何其他值,则必须满足FOREIGN KEY约束。