【问题标题】:.NET: Allow NULLS in DB fields?.NET:在 DB 字段中允许 NULLS?
【发布时间】:2010-04-14 09:35:50
【问题描述】:

我有重构 SQLServer DB 的任务....很多表和列“允许 NULLS”,这是一种好习惯吗...

我似乎记得 CSLA.NET 的作者说在数据库中允许空值是非常糟糕的做法......

如果是这种情况,我的替代方案是什么?

从所有列中删除所有“ALLOW NULLS”......并且在数字列中使用值 -1 例如??

我非常感谢任何人的任何意见。

我目前正在使用我的数据库中的模型(来自实体框架),并且“ALLOW NULLS”为空的 db 列......并且一些存储过程要求我有一个默认值......即 BOOLEAN 要求默认为 FALSE ... 但它为 null..

好吧,我不想偏离我原来的问题,从我能收集到的信息中,ALLOW NULLS 是一件坏事......那么我该如何解决这个问题?

非常感谢任何帮助

【问题讨论】:

标签: c# .net sql sql-server-2008 null


【解决方案1】:

毫无疑问,应尽可能避免使用 NULL,因为这些问题可能会给索引和查询语法带来一些问题。

由于 NULL 可能引入的问题,人们一直在推动停止使用它们。然而,像大多数这样的动作一样,它已经失控,以至于有些人狂热地坚持绝对不应该在数据库中使用 NULL。我在这个营地待了很多年,才发现它有点过分热心。

答案介于两者之间。应尽可能避免使用 NULL,但存储它们确实有正当的商业原因。

很多时候你需要存储一个可选的数值,很多人会告诉你只存储一个零来表示“没有值”,但这是一个更糟糕的反模式,存储一个真正意味着其他东西的神奇值。如果你不能对一个字段使用零怎么办,因为零也被认为是一个有意义的值,或者因为这个值被用作除数的倍数,所以你需要使用其他一些神奇的值(-1? ) 在这种情况下,对于该字段,现在您遇到了更严重的问题,因为您的所有可选数字字段现在的行为都不同。哎呀。

日期是可空字段的更有吸引力的候选者。人们在 .NET 中使用的标准“无值”是默认未分配的 DateTime 值,即 DateTime.MinValue,或者更具体地说是 0001 年 1 月 1 日。但是,您不能将此魔术值写入 SQL 数据库,因为默认最小值为SQL Server DATETIME 字段是 1973 年 1 月 1 日。您现在必须有一些东西来检查您在将这些值写入和读取数据库时是否正确翻译了这些值,并且您必须在所有检查的地方都有防御性编码对于您的日期字段是否小于 SqlDateTime.MinValue,而不仅仅是检查它们是否等于 DateTime.MinValue。双眼。

我的偏好是处理真实的价值,而不是构建大量人工构造来隐藏该领域的真实含义和用途。如果一个字段很可能没有值,请将其设为可空,并在您的应用程序对象中使其也可空(如果您的语言支持这样的事情)。然后,每当您使用该字段时,您都需要考虑在它为 NULL 的情况下应该做什么,但这实际上是一件好事。一般来说,我反对让开发人员在不必要的代码复杂性上浪费脑力,但那是因为它把注意力从正在解决的真正业务问题上转移了;然而,在这种情况下,缺乏价值是真正的业务问题的一部分,必须深思熟虑。如果您只是默认这些值,那么编写公式或算法的开发人员将不太可能考虑那些缺少值的边缘条件,甚至可能当时甚至没有意识到这些值有可能丢失.

【讨论】:

  • new DateTime() != DateTime.MinValue - 除此之外,很好的答案,+1
【解决方案2】:

Null 有时是一个有效的列值,但我建议更好的做法是添加默认值并使列不为空。

如果您需要考虑现有数据,则必须进行如下更新:

update TableA set ColumnA = 'default value' where ColumnA is null 

...如果您想对现有数据施加“非空”。

如果没有合理的默认值,那么 null 可以是一个完全有效的列值 - 但通常有一个不错的默认值可用。

【讨论】:

  • 我发现很多不是字符串的字段(谁用空字符串“作弊”)通常不能用默认值填充。比如生日、最后编辑的 id 等等。如果它是一个未知值,则 if 应保留为 null - 但大多数人无法掌握该概念。 =|
  • 我不喜欢使用空白来替代 null - 空白值表明这是一种选择。在描述字段中使用“未输入描述”而不是 null 将是一个合理的默认值,并且可以在以后节省强制转换为空值。像许多事情一样,在散布各处的空值很容易被默认为更好的信息和针对空值的圣战之间存在一种快乐的媒介,其中有效信息是第一个牺牲品。
【解决方案3】:

使用空值是轻微的非规范化可以带来很大的性能优势的情况。在现实世界中,NULL 值是一种完全有效的方式来表示一个值尚未 记录下来。这尤其适用于布尔 (BIT) 值和可选数值。

纯粹主义者会让你创建一个带有左连接的新表来记录这个值。现实主义者将更改现有表并添加空值。

肯定有空值相关的情况。出于完全相同的原因,Nullable 泛型被添加到值类型的 .net 框架中。

【讨论】:

    【解决方案4】:

    NULL 是人类脸上的一个污点,应该从存在中根除。然而,不幸的是,当前的系统和语言(尤其是 SQL)无法完成对当前思想进行如此彻底改革的任务。事实上,SQL 是这种讽刺的主要肇事者。

    因此,在现实世界中,我的建议是尽可能避免使用 NULL,但要接受现实,即有时没有简单的替代方案。

    【讨论】:

    • -1:什么?!?那么,您是那些使用 -1 表示未知整数、1900-1-1 表示未知日期等等的人之一?
    • 嗯,采取不受欢迎的立场肯定是危险的。不,我不是那些人中的一员。我赞成数据的 5NF 和 6NF 规范化,以及与这种方法很好地配合使用的 DBMS 和相关工具的构建。当然,由于那些对我投反对票的人可能不知道我在说什么,我不希望我的代表很快回来。具有讽刺意味的是,最高投票的答案基本上同意我的立场,即 NULL 是不好的,但通常是不可避免的。 OTOH,我不同意@Mike 的暗示,即魔法值是唯一的选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    • 2011-01-09
    • 2011-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多