7

数据库架构

我有这个领域:

  • 标题(字符串)
  • 字幕
  • 描述(字符串)

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

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

4

8 回答 8

19

通常的合同是:

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

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

这里唯一的技术点是:在 PostgreSQLNULL中可以比长度为零的字符串更有效地存储。如果这对你来说真的很重要……我们不知道。

于 2012-11-24T14:27:33.670 回答
9

专家意见:避免 NULL

与关系数据模型的创建者/发现者 ( Codd 博士) 合作的Chris (CJ) Date博士明确表示:“不,您不应该使用 NULL。”。阅读他的书A Guide To The SQL Standard进行大量讨论。

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

解决方案:

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

规则的例外

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

示例例外:Postgres中,在数百万行的表中使用XML 数据类型时。我需要反复搜索尚未记录值的行(缺失值)。我无法存储空字符串,因为 Postgres 强制执行仅存储有效 XML 的规则,而空字符串不是有效的 XML 文档。所以我允许在那个 XML 列中使用 NULL。

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

于 2014-02-20T06:28:45.630 回答
4

关于这一点,大多数人已经说过了,但是我认为如果您最终认为使用 NULL 或“”作为“无价值”(简单地说)之间是 50/50,还有一件事需要考虑。

在 MySQL 中,如果您对列有否定条件,则不会“捕获”值 NULL。例如。

where column != 'text'

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

where column != 'text' OR column IS NULL

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

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

于 2012-11-24T17:43:52.657 回答
2

您应该始终使用 NULL 来表示该列没有值,因为即使是空字符串也是一个值。

于 2012-11-24T14:28:11.690 回答
1

您需要确定“null”和空字符串的值在您的应用程序中是否意味着不同,或者它们都只是意味着“无数据”。如果是后者,那么这通常只是一个偏好问题,但你必须随之而来 - 尽量不要在给定字段中混合“空”值和空值。

通常,'null' 提供了更好的“无数据”概念,但与空字符串相比,它在应用程序中使用起来有些麻烦。但是使用空字符串代替空字符串可能会被视为过早的优化,并且在将来的某个时候将无法引入需要区分空字符串和空字符串的功能。

另一方面,有些 DBMS 不在字符串列中存储空值,只是在空字符串中存储。我会使用空值,但要使用完善且有据可查的合同(即“此字段从不包含空值,空标题意味着没有标题”,在列上强制执行 NOT NULL 约束),您可以采取任何您喜欢的方法。

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

而且,当然,您必须考虑客户的期望。但是,当您创建客户端尚未访问的数据库时,由您决定并适当地记录它。

于 2012-11-24T14:35:33.380 回答
1

这并不严格适用于您的情况,但为了完整起见,我会提到它:不强制执行 NULL 外键。

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

顺便说一句,Oracle将空字符串存储为 NULL。保证 VARCHAR2 继续以这种方式运行,而 VARCHAR 可能(有朝一日)被更改以符合 SQL 标准并区分空字符串和 NULL。其他 DBMS(据我所知)确实做出了这种区分。

于 2012-11-24T15:45:12.780 回答
0

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

于 2012-11-24T15:18:35.073 回答
0

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

或者你只是不知道?示例:您收到了“中间名首字母”字段留空的表格。

于 2012-11-24T18:47:40.187 回答