当前位置: 首页 > 面试题库 >

标准使用“ Z”而不是NULL来表示丢失的数据?

柯琛
2023-03-14
问题内容

除了是否应使用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。

这似乎证实了对该问题的大部分消极反应。除了使用公认的6NF方法来设计NULL之外,还使用特殊值来“尽可能避免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 不再提供仍然有效的数据
  • 您刚刚创建了自己的千年错误
  • 等等。

这等效于重新构造抽象,以使所有属性始终可以具有有效值。它与将特定含义隐式编码为任意选择的值明显不同。

仍然,解雇承包商。



 类似资料:
  • 我使用以下方法创建了web服务: 过滤器在XSD模式中定义如下: 对象筛选器看起来像这样: 我发出请求: 但是,当在我的应用程序中读取请求时,我看到属性值包含“[value:null]”,而不是“someValue”。属性类型和属性名称都可以。

  • 问题内容: 如果使用方法,则每次通过此方法写入文件时,都会丢失旧数据。是否可以通过写入文件而不会丢失旧数据? 问题答案: 使用采用和的构造函数 并将布尔值设置为。这样,你写入的数据将被附加到文件的末尾,而不是覆盖已经存在的数据。

  • 我必须记录响应正文和响应标题。为此,我使用了拦截器和ContentCachingResponseWrapper类(我也尝试了filter,但结果相同)。当我将两者结合起来时,我会丢失一些标题信息,但如果我只使用拦截器,则不会丢失。 我的dispatcherServlet: 当我在拦截器的postHandle中使用ContentCachingResponseWrapper时: 标题结果: {设置Co

  • 问题内容: 如PHP文档中所述,当使用包含长整数的数据结构时,它们将被转换为浮点数。解决方法是使用,而是将其保留为字符串。当荷兰国际集团这样的值,将编码这些数字背到大的整数: 使用此方法进行正确的数据往返很容易出错。如果属性包含,则数字字符串应保留为字符串,它将被编码为整数。 我想从服务器获取一个对象,修改一个属性,然后将整个数据结构放回去。我需要保留原始类型。除了要处理的属性外,我不想保留其他属

  • 有没有办法在没有导入语句的情况下使用标准库类扫描仪? 除了反编译标准库和添加所有的函数之外,我的教授是一种包括那些不希望你真正完成的非常困难的问题的人。java文件到这个项目我有点不知所措。 编辑:为了澄清,这是实验室描述的确切措辞:“使用扫描仪从用户那里获取整数值。

  • 问题内容: 我有一个名为Person的表,我已经在hibernate中映射了该表,我已经有一些不想删除的数据。我需要添加一个称为地址的新列,任何想法如何在hibernate状态下进行? 提前致谢.. 问题答案: 可能您不会被迫使用Hibernate创建/更新数据库架构。我假设您的配置中包含以下内容: 只需将值更改为“ validate”,对映射进行更改并分别执行ALTER TABLE语句即可。 另