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

数据库架构

我有这个字段:

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

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

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

通常的合同是:

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

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

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

专家意见:避免使用NULL

Chris(CJ)Date与关系数据模型( Codd博士 )的创建者/发现者合作,清楚地说:“不,你不应该使用NULL。” 阅读他的书“SQL标准指南”进行了大量讨论。

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

解:

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

规则的例外

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

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

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

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

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

 where column != 'text' 

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

 where column != 'text' OR column IS NULL 

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

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

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

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

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

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

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

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

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

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

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

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

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

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