我只是进入一个项目,它有一个相当大的数据库后端.我已经开始挖掘这个数据库了,95%的字段都可以为空.
这是数据库世界中的常规做法吗?我只是一个卑微的程序员,而不是DBA,但我认为你想要将可空字段保持在最低限度,只有在它们有意义的地方.
如果大多数列可以为空,它是否是"代码味道"?
hyt*_*ayr 17
根据我的经验,默认值通常是异常,NULL是常态.
没错,nulls很烦人.
它也非常有用,因为null是"NO VALUE"的最佳指标.具体的默认值非常具有误导性,您可能会丢失信息或引起混乱.
Bil*_*win 14
任何开发了数据输入应用程序的人都知道在进入时某些字段是多么常见 - 即使是对业务至关重要的字段,也要解决@Chris McCall的答案.
然而,"代码味道"仅仅是指示某些东西可能以草率的方式编码的指示符.你使用气味识别需要更多调查的东西,而不一定是必须改变的东西.
所以,是的,如果你如此一致地看到可以为空的列,那你就是可疑的.这可能表明有人在懒惰,或者害怕NOT NULL明确地宣布专栏.你可以证明做自己的分析是正确的.
Joe*_*win 10
我是Extreme NO阵营:我总是避免使用NULL.暂不考虑他们实际意味着什么(因为与不同的人交谈,你会得到不同的答案,如"没有价值","未知价值","失踪","我的姜猫叫做Null"),这是最糟糕的问题NULL的原因是它们经常以神秘的方式破坏你的查询.
我已经失去了调试某人查询的次数(好吧,可能是9次),并将问题追溯到针对NULL的联接.如果您的代码需要ISNULL来修复连接,那么您可能也失去了索引适用性和性能.
如果你也有来存储"丢失/未知/空/猫"值(和它的东西,我宁愿避免的),最好是要明确一下.
熟悉NULL的人可能不同意.NULL使用倾向于将SQL人群分散到中间.
根据我的经验,重度使用NULL与数据库滥用正相关,但我不会将其作为一些自然法则将其刻入石碑中.我的经验只是我的经历.
编辑:额外的想法.那些像我一样的反空种族主义者可能会比那些支持NULL的人更加兴奋.我不认为狂犬病归一化器会对它们的表上可能带有NULL的粗糙边缘感到满意.很多空值可能表明数据库开发人员没有进行大规模的标准化.因此,不是NULL表示代码是"坏",它可能会建议开发人员在规范化上的哲学立场.也许这是达成的.只是一个想法.
不知道我是否认为它总是一件坏事,但是如果列是因为单个记录(或者可能是少数)需要有值而大多数没有,那么它表示一个非常平坦的表结构.如果您看到列名称如"addr1","addr2","addr3",那么它会发臭!
我敢打赌,您拥有的大多数列都可以删除并在其他表中表示.您可以通过外键关系找到"非空"的.这将增加您将要执行的连接,但是执行"where col1 is null"可能更具预期性.
我认为应该避免可以为空的列.只要域的语义使得可以使用明确指示缺失数据的值,就应该使用它而不是NULL.
例如,让我们想象一个包含Comment字段的表.大多数开发人员会在此处放置一个NULL来表示列中没有数据.(并且,希望是一个不允许零长度字符串的检查约束,以便我们有一个众所周知的"值"来表示缺少值.)我的方法通常是相反的.该Comment柱是NOT NULL和一个零长度的字符串表示缺少的值.(我使用检查约束来确保零长度字符串实际上是一个零长度字符串,而不是空格.)
那么,我为什么要这样做呢?两个原因:
NULL在SQL中需要特殊的逻辑,这种技术可以避免这种情况.NULL.例如,如果您使用Microsoft的ADO.NET,则常量DBNull.Value指示NULL,您必须测试它.在NOT NULL列上使用零长度字符串可以满足需要.尽管如此,在许多情况下,NULLs都很好.事实上,我不反对在上面的场景中使用它们,尽管这不是我喜欢的方式.
无论你做什么,都要善待那些会使用你的桌子的人.保持一致.让他们SELECT充满信心.让我解释一下我的意思.我最近参与了一个项目,其数据库不是我设计的.几乎每列都可以为空,没有任何限制.什么代表没有价值,没有一致性.它可能是NULL一个零长度的字符串,甚至是一堆空格,而且往往是.(我不知道那些价值观如何到达那里.)
想象一下开发人员必须编写的丑陋代码,以便Comment在此场景中找到所有缺少字段的记录:
SELECT * FROM Foo WHERE LEN(ISNULL(Comment, '')) = 0
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,有些开发人员认为这是完全可以接受的,即使是正常的,尽管可能会影 更好的是:
SELECT * FROM Foo WHERE Comment IS NULL
Run Code Online (Sandbox Code Playgroud)
要么
SELECT * FROM Foo WHERE Comment = ''
Run Code Online (Sandbox Code Playgroud)
如果您的表设计得当,可以依赖上述两个SQL语句来生成高质量的数据.
简而言之,我会说是的,这可能是代码的味道。
列是否可为空非常重要,应谨慎确定。应该为每一列评估该问题。我不相信默认的单个“最佳做法” NULL。对我而言,“最佳实践”是在表的设计和/或重构过程中彻底解决可空性问题。
首先,您的主键列都不会为空。然后,我强烈倾向于NOT NULL寻找任何外键。
我考虑的其他一些事项:
NULL应该强烈避免的标准:
money列- 确实有可能未知的金额吗?
NULL可以最经常证明其合理性的标准:
datetime列-没有保留日期,因此NULL实际上是您的最佳选择
其他数据类型:
char/ varchar列-用于代码/标识符- NOT NULL几乎仅用于
int列-主要用于NOT NULL除非您想要区分未知响应的“子代数”之类。