Varchar列:Nullable与否

时间:2010-06-08 19:59:03

标签: sql-server null types nullable sqldatatypes

组织中的数据库开发标准声明varchar字段不应允许空值。它们的默认值应为空字符串(“”)。我知道这使得查询和连接更容易,但是今天,我的一位同事质疑我为什么这个标准只存在于varchar类型而不是其他数据类型(int,datetime等)。我想知道其他人是否认为这是一个有效的,可防御的标准,或者varchar是否应该被视为与其他数据类型的字段相同?

我认为此标准有效,原因如下:

我认为空字符串和空值虽然技术上不同,但在概念上是相同的。空的零长度字符串是不存在的字符串。它没有任何价值。但是,数值0与NULL不同。

例如,如果名为OutstandingBalance的字段的值为0,则表示剩余的金额为0.00。但是,如果相同的字段为NULL,则表示该值未知。另一方面,名为CustomerName的值为“”的字段与NULL值基本相同,因为两者都表示名称不存在。

我在某处读到空字符串与NULL的类比是空白CD与没有CD的类比。但是,我认为这是一个错误的类比,因为空白的CD仍然存在于物理上并且仍然具有没有任何有意义的数据写入其中的物理数据空间。基本上,我认为空白CD相当于一串空格(“”),而不是空字符串。因此,我认为一串空格是一个与NULL分开的实际值,但是一个空字符串是概念上等价于NULL的值。

如果我对可变长度琴弦的信念有效,请告诉我,如果不是,请告诉我。我已经阅读了几篇关于这个主题的博客/论点,但仍然没有看到NULL和空字符串之间真正的概念差异。

2 个答案:

答案 0 :(得分:17)

它几乎归结为这个 - 在你的应用程序中,对于一个特定的字符串,有一个空字符串与没有字符串之间有区别吗?

如果没有区别,那么您所遵循的标准就可以了。

如果您发现存在差异,则null具有明显的含义,应该被允许。

根据我的经验,null通常被建模为unknown

这是一个更具体的例子 - 人的中间名字:

  • 如果您知道中间名,则填充值
  • 如果您知道此人没有中间名,请使用空字符串('')
  • 如果您不知道某人是否有中间名,null可能更合适

同样,如果你的应用程序对待没有中间名的人以及那些未知的人,那么使用空字符串是有意义的(即使它确实意味着丢失一些信息)。

答案 1 :(得分:0)

不,null是一个非常独特的价值。例如 - 只有十几个中的一个 - null可能意味着“我们根本没有值”,而空字符串意味着“我们有一个答案而且它什么都没有。”这将是有用的,例如,作为一个问题的答案 - 从来没有得到答案或答案是什么......

那里有一张漂亮的白皮书,里面写着“NULL的18个含义” - 我不记得整数是什么! ANyway,至少在20世纪90年代早期,那篇论文已经出现在那里,如果你能找到它,那真是太棒了 - 我还没有进行网络搜索。

null的真正问题是它们可以“错误地”改变返回的行。例如,如果你说

从fubar中选择strcol1,datecol2,someint3 ......

如果strcol1恰好为null,则不会为该行返回值,因为隐含的“strcol1不为空” - 因此可能缺少整行。

对于所有RDBMS系统都不是这样,但对于某些系统已经有一段时间了,所以如果您希望将代码从一个RDBMS移动到另一个RDBMS,那么在处理空值时应该非常小心。 / p>

另一点:Oracle - 或者至少是某些版本的Oracle - 会将空字符串静默地转换为null!这确实令人愤慨,但不知何故,他们已经“永远”地投入生产。小心!我的解决方案是使用其他字符串来表示“空字符串”,通常是单个空格字符。