最好使用空值作为”还是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”字段留空。