除了是否应使用NULL之外,我还负责一个现有数据库,该数据库使用NULL表示“丢失或从未输入”数据。它不同于空字符串,这表示“用户设置了此值,并且他们选择了’空’”。
该项目的另一个承包商坚决主张“对于我来说不存在NULL;我从不使用NULL,并且任何人都不应使用NULL”。但是,令我困惑的是,由于承包商的团队确实承认“缺少/从未输入”和“故意空着或由用户指示为未知”之间的区别,因此他们在整个代码和存储过程中使用单个字符“ Z”在整个数据库的其余部分中,表示“缺少/从未输入”,其含义与NULL相同。
尽管我们共享的客户要求更改此设置,而我也支持此要求,但是该团队将此作为比我更先进的DBA中的“标准做法”进行了引用。他们不愿意仅根据我的无知请求更改为使用NULL。那么,有人可以帮助我克服我的无知吗?在SQL专家中,是否有任何标准或一小群人,甚至是一个大声的提倡使用“ Z”代替NULL的人?
我有承包商的回应要补充。当客户要求删除特殊值以允许无数据列中的NULL时,他说的是这句话:
基本上,我设计数据库时要尽可能避免NULL。 这是基本原理: ―不需要 在字符串[VARCHAR]字段中使用NULL,因为空(零长度)字符串提供的信息完全相同。 鈥 甲NULL在一个整数字段(例如,ID值)可以通过使用永远不会在数据中出现的值(例如,-1的整数IDENTITY场)进行处理。 鈥 在日期字段中的NULL极易引起日期计算的并发症。 例如,在计算日期差异(例如[RecoveryDate]和[OnsetDate]之间的天数差异)的逻辑中,如果一个或两个日期为NULL,则该逻辑将爆炸- 除非为两个日期都明确允许为NULL。那是额外的工作和额外的处理。如果将“默认”或“占位符”日期用于[RecoveryDate]和[OnsetDate](例如“ 1/1/1900”),则数学计算可能会显示“异常”值-但日期逻辑不会爆炸。 传统上,NULL处理是开发人员在存储过程中犯错的领域。 在我作为DBA的15年中,我发现最好尽可能避免使用NULL。
基本上,我设计数据库时要尽可能避免NULL。 这是基本原理:
―不需要 在字符串[VARCHAR]字段中使用NULL,因为空(零长度)字符串提供的信息完全相同。
鈥 甲NULL在一个整数字段(例如,ID值)可以通过使用永远不会在数据中出现的值(例如,-1的整数IDENTITY场)进行处理。
鈥 在日期字段中的NULL极易引起日期计算的并发症。 例如,在计算日期差异(例如[RecoveryDate]和[OnsetDate]之间的天数差异)的逻辑中,如果一个或两个日期为NULL,则该逻辑将爆炸- 除非为两个日期都明确允许为NULL。那是额外的工作和额外的处理。如果将“默认”或“占位符”日期用于[RecoveryDate]和[OnsetDate](例如“ 1/1/1900”),则数学计算可能会显示“异常”值-但日期逻辑不会爆炸。
传统上,NULL处理是开发人员在存储过程中犯错的领域。
在我作为DBA的15年中,我发现最好尽可能避免使用NULL。
这似乎证实了对该问题的大部分消极反应。除了使用公认的6NF方法来设计NULL之外,还使用特殊值来“尽可能避免NULL”。我以开放的态度发布了这个问题,很高兴我了解到更多有关“空值有用/空值很邪恶”的辩论,但是现在我很乐意将“特殊值”方法标记为完全废话。
空(零长度)字符串将提供完全相同的信息。
不,不是。在我们正在修改的现有数据库中,NULL表示“从未输入”,空字符串表示“输入为空”。
是的,但是成千上万的开发人员已经犯下了数千次错误,而且避免这些错误的教训和注意事项也已得到记录并记录在案。如此处所述:无论您接受还是拒绝NULL,缺失值的表示都是一个已 解决的问题 。无需仅仅因为开发人员不断犯下易于克服(且易于识别)的错误而发明新的解决方案。
作为一个脚注:我已经成为DBE和开发人员已有20多年了(对于我来说,这足够时间来了解数据库工程师和数据库管理员之间的区别)。 在我的整个职业生涯中,我一直都处于“ NULL是有用的”阵营,尽管我知道几个非常聪明的人不同意。我对“特殊价值”方法非常怀疑,但是对“如何避免以正确方式避免NULL”的学术知识不够扎实。我一直喜欢学习新事物,而20年后,我仍然有很多东西要学习。感谢所有为此做出有益讨论的人。
解雇您的承包商。
好吧,很严重,这不是标准做法。可以简单地看出这一点,因为我曾经使用过的所有RDBMS都实现NULL,逻辑为NULL,考虑外键中的NULL,对COUNT中的NULL具有不同的行为,等等,等等。
我实际上认为使用’Z’或任何其他占位符会更糟。您仍然需要代码来检查“ Z”。但是您还需要证明“ Z”并不意味着“ Z”,而是其他含义。并且您必须确保阅读了此类文档。然后,如果“ Z”成为有效数据,会发生什么?(例如字段的首字母缩写?)
从根本上讲,即使不争论NULL与’Z’的有效性,我也会坚持要求承包商遵守公司内部的标准惯例,而不是其公司内部的惯例。在替代标准实践环境中建立他的标准实践会引起混乱,维护开销,误解,最终会增加成本和错误。
在某些情况下,我认为使用NULL替代方法是有效的。但是,只有这样做才能减少代码,而不是创建需要考虑的特殊情况。
例如,我已将其用于日期绑定数据。如果数据在开始日期和结束日期之间有效,则可以通过不使用NULL值来简化代码。取而代之的是,空开始日期可以替换为“ 1900年1月1日”,空结束日期可以替换为“ 2079年12月31日”。
这仍然会改变预期的行为,因此应谨慎使用:
WHERE end-date IS NULL
这等效于重新构造抽象,以使所有属性始终可以具有有效值。它与将特定含义隐式编码为任意选择的值明显不同。
仍然,解雇承包商。