最好使用空值作为''还是NULL?

时间:2012-11-24 14:18:11

标签: mysql ruby-on-rails database postgresql database-design

数据库架构

我有这个字段:

  • title(string)
  • 字幕
  • description(string)

最好将默认值设置为空字符串' NULL

为了更好的读/写和大小存储性能

8 个答案:

答案 0 :(得分:14)

通常的合同是:

  • NULL表示“没有可用信息”。
  • ''表示“有可用的信息。它只是空的。”

除此之外,自NULL在任何语言中发明以来,都有许多哲学讨论,而不仅仅是SQL。

这里唯一的技术要点是:在PostgreSQL中NULL可以比长度为零的字符串更有效地存储。如果那在你的情况下真的很重要......我们无法知道。

答案 1 :(得分:7)

专家意见:避免使用NULL

与关系数据模型(Dr. Chris (C.J.) Date)的创建者/发现者合作的

Dr. Codd清楚地说:“不,你不应该使用NULL。”阅读他的书A Guide To The SQL Standard进行大量讨论。

他和其他专家一起认为,对于各种理论和实践问题,NULL会带来太多的风险,混乱和问题,使它们值得一试。

解决方案:

  • NOT NULL的每一列上添加约束。
  • 如果有意义,请为每列添加默认值DEFAULT。对于文本类型列,默认值可以是空字符串('')。或者默认值可能是您根据需要随意选择和使用的某些措辞,例如“EMPTY”或“NOT-AVAILABLE”。在某些列上,您可能不需要默认值,这意味着如果用户/应用程序未提供值,您希望拒绝记录的插入或更新。

规则的例外

以上是一个很好的规则,我习惯性地遵循它。但是,每条规则都有例外。在极少数情况下,我在允许NULL的情况下做了例外。

示例异常:Postgres中使用数百万行表中的XML data type时。我需要重复搜索尚未记录的行(缺失值)。我不能存储空字符串,因为Postgres强制执行仅存储有效XML的规则,并且空字符串不是有效的XML文档。所以我在那个XML列中允许NULL。

您可能认为我可以存储不包含数据的最小XML文档。但我不知道如何有效地索引,以区分具有记录数据的行和没有记录数据的行。我可以在NULL上创建索引。

答案 2 :(得分:3)

大多数人已经说过这个了,但我认为还有一件事需要考虑 if 你最终认为在使用NULL或“”作为“无价值”(简单说出)之间是50/50

在MySQL值中,如果列上的条件为负,则不会“捕获”NULL。例如

where column != 'text'

只返回“column”没有值“text”的行,但是找不到“column”为NULL的行,如果你想找到你必须使用的这些行:

where column != 'text' OR column IS NULL

我自己仍然喜欢使用NULL并在保存之前将空字符串更改为nil,我认为最好知道数据库中的“空值”始终为NULL。

另一方面,在某些情况下,您可能希望使用“无值”(NULL)和“空值”(“”)之间的差异。但我在某些应用程序中从未遇到过这种情况 - 但是。

答案 3 :(得分:2)

你应该总是使用NULL来表示列没有值,因为即使空字符串是值。

答案 4 :(得分:2)

您需要确定“null”和空字符串的值在您的应用程序中是否意味着不同,或者它们两者只是意味着“没有数据”。如果后者是这种情况,那么通常只是一个偏好问题,但你必须得到结果 - 尽量不要在给定字段中混合'null'值和空值。

通常“null”给出了“无数据”的更好概念,但与空字符串相比,在应用程序中使用它会稍微麻烦一些。但是,然后使用空字符串而不是空字符可能被视为过早优化,并且将来在某个时间不可能引入需要区分空值和空字符串的功能。

另一方面,有些DBMS不在字符串列中存储空值,只是空字符串。我会使用空值,但是已经建立并记录了合同(即“此字段永远不会包含空,空标题意味着没有标题”,在列上使用NOT NULL约束强制执行),一直遵循您可以采用您喜欢的任何方法。

如果您关注性能,则需要阅读正在使用的DBMS文档并自行进行一些测试。如果您希望空值非常频繁,您可以检查“稀疏列”是否有任何帮助 - 一些DBMS将这些作为有效存储频繁出现的空值的方法,但它们通常有一些缺点,如一般(检索非空值时的性能损失,或类似的事情。

当然,你必须考虑到客户的期望。但是当您创建尚未被客户访问的数据库时,您可以自行决定并正确记录它。

答案 5 :(得分:0)

仅在数据未知或不适用时才使用Null值。在所有其他情况下,在编写涉及NULL值的数据的查询时,需要使用“”(空值)作为特殊考虑因素,这通常很困难。< / p>

答案 6 :(得分:0)

这不是严格适用于您的情况,但我会提到它的完整性:不强制使用NULL外键。

如果您的字段foreign_id是引用其他表的外键,则仅当foreign_id包含非NULL值时才会强制执行。 p>

BTW,Oracle stores empty string as NULL。保证VARCHAR2继续以这种方式运行,而VARCHAR可能(一天)被更改为符合SQL标准并区分空字符串和NULL。其他DBMS(我知道)确实做出了这种区分。

答案 7 :(得分:0)

这取决于。你知道价值是空的吗?示例:已知人员没有中间首字母。

或者你只是简单地不知道?示例:您收到一个表单,其中“Middle Initial”字段留空。