Pretext,我熟悉NULL值和空字符串之间的语义差异。
我有一个MySQL表,我用它的IP地址(作为一个字符串)存储了很多主机名,并想知道在主机名无法解析的情况下看起来更自然(或有效存储)。
NULL值或空字符串(在这种情况下,它可能应该是VARCHAR而不是CHAR)
我倾向于使用NULL值,但我希望确认或不确认。
答案 0 :(得分:4)
在 MyISAM MYSQL中,每行保存一位不使用NULL 。正如here所述:
声明列NULL可以减少允许的最大列数。对于MyISAM表,NULL列需要行中的额外空间来记录它们的值是否为NULL。每个NULL列需要额外一位,向上舍入到最近的字节。
看看here:
此外,虽然NULL本身不需要任何存储空间,但如果表定义包含任何定义为NULL的列,则NDBCLUSTER每行保留4个字节,最多32个NULL列。 (如果定义的MySQL Cluster表有超过32个NULL列,最多64个NULL列,则每行保留8个字节。)
此外它还使数据库工作更快,其中here(取自stackoverflow - @DavidWinterbottom链接对我不起作用,我添加了一个不同的源)
MySQL更难以优化引用可为空的coumns的查询,因为它们使索引,索引统计和值比较更加复杂。可空列使用更多存储空间,并且需要在MySQL内部进行特殊处理。对可为空的列建立索引时,每个条目需要一个额外的字节,甚至可以在MyISAM中将固定大小的inded(例如单个整数列上的索引)转换为可变大小的列。
在大多数情况下,当与COUNT()
和其他聚合函数结合使用时,非NULL值的行为更具可预测性,但您也可以根据需要看到NULL行为。
如前所述here,并非所有组(聚合)函数都忽略NULL ,例如,COUNT()
会为您提供COUNT(*)
的不同结果包含NULL值的列。
另一方面,因为其他指出NULL更好地反映了条目的含义 - 它是一个未知值,如果你想计算所有主机,你可能COUNT()
的行为与它完全一样。
答案 1 :(得分:1)
Oracle解决了这个问题并解释了两者。
Mysql没有,我不是在判断它,但是我不喜欢它,所以尽可能使用NULL来“标准化”我的代码。
另外,从关键字的重要性来看,NULL正是你想要的,因为它在db语义中意味着“未知”。 (如果我错了,请纠正我)
答案 2 :(得分:1)
首先:仔细考虑 NULL 和空字符串的不同语义。
第二:认识到索引和过滤在空字符串上比在 NULL 上更好,更有效,所以不要使用后者,当你真正的意思是前者。
第三:认识到使用 NULL 的所有表达式都容易受到三值逻辑的非直观性的影响,除非NULL被虔诚地合并为 Empty-首先是字符串(或其他一些上下文有效的值)。特别是,排除中间的定律不再适用,因此当 A 的评估需要评估时,表达式 A或~A 不再是重复真实的。 NULL 术语。忘记这可能导致非常微妙和难以定位的错误。
not-equals运算符定期公开:
When A has the value NULL:
The expression A = 0 returns false;
The expression A <> 0 returns false; and
The expression A OR NOT A returns false!
<强>更新强>:
我想我的观点的本质是它们不是同一种生物,而是非常不同的野兽。每个都有它的位置。第二个地址字段应始终为非空(除非您打算允许输入部分或不完整的地址),并且它的默认值应始终是Empty-String的有效和已知值。 NULL应限于以后提供有效和已知值的情况,实际上o表示某种必须解决的验证失败。
来自以下OP:
不会更新行。在插入时,有一个IP 地址或没有(因为无法解决)。
回复:
然后我建议使用 Empty-String 作为默认值,并使字段为NON-NULL。只有在必要时才使用 NULL ,因为它有微妙的缺点。
答案 3 :(得分:0)
我建议你使用NULL
,而NULL的类型与string不同。例如,使用此值过滤掉行或检测该字段中的值类型等等更容易。