在列中放置默认值有什么好处?

时间:2009-07-31 15:39:13

标签: sql sql-server database database-design

如果这个问题过于宽泛,我很抱歉。我是一名DBA,我正在与一个开发人员合作,他认为列默认值是一个坏主意,只是将列设置为禁止空值就足够了。

我正在从开发人员的角度寻找列默认值的好处。感谢您的评论。

11 个答案:

答案 0 :(得分:7)

它有助于版本控制。例如,如果旧代码(INSERT语句)需要一个包含10列的表,并且旧代码必须使用带有12的新表,那么您需要为新列提供默认值,或者使新列可以为空

它还取决于NULL对于给定列的确切语义,因为默认选择也是对列中NULL的选择。空标记是否意味着未知,不可知,尚未改变,未知未来的某些东西,未知未来的东西。这些标记略有不同,NULL只能表示其中一个。

答案 1 :(得分:5)

如果要向现有表添加列并且不希望列可为空,则必须提供默认值。

答案 2 :(得分:3)

默认值使得在表中插入新行变得容易得多 - 如果默认值为OK,则不需要显式指定具有默认值的所有列并在INSERT语句中提供值(如getdate()表示“LastChangeOn”日期列。)

我没有看到任何理由为什么你使用列上的默认值,实际上,当有一个有效且合理的默认值时。我不明白为什么你的开发人员对默认值有这样的厌恶 - 它们总是可以在初始INSERT中被覆盖(之后不再发挥作用)。

马克

答案 3 :(得分:3)

许多开发人员不喜欢将业务逻辑放在数据库中。开发人员可能会认为他正在失去控制权(他可以编写例程将自己的默认值设置为null以外的其他东西)。我不确定他是否会认为这样做是为了帮助他/从他的盘子里完成一些任务。

我处理的数据库是第三方应用程序的后端,我对应用程序的处理方式有限(比如有默认值)。我不能强制应用程序在所有数据输入面板上都有一个默认值,所以我想在数据库中的一个字段上放置一个默认值,我有控制权。我无法访问他们的代码,我们的用户也不想等待升级。

答案 4 :(得分:3)

列默认设置允许您从代码或应用程序逻辑中删除许多创建记录的麻烦。

优势#1 :如果你有一个包含2列用户信息和20列tinyint / boolean字段的表,假设它们是隐私设置,你可以创建一个新记录该表没有DEFAULT值,您必须指定查询中的每一列。默认情况下,您可能希望这些记录具有常见设置,您可以使用DEFAULT值进行设置。当您INSERT记录时,您只需要指定两个用户信息字段,而且,您的记录是使用一组很好的常见隐私设置创建的。之后你可以单独调整标志。

优势#2 :向前兼容!如果你的代码中有一堆INSERT,然后添加了一些列,那么如果你没有指定一个列,那么你将不得不返回并修改所有INSERT个。 DEFAULT值(假设NULL不会削减它的常见情况)。通常没有必要更新新列的旧代码(因为旧代码本质上不关心新列),所以这将是@ $$中的巨大痛苦如果你不得不开始回头并处理代码中的每一个新列。

答案 5 :(得分:2)

这取决于您的要求。如果您的规则要求最小值并且NULL不被视为有效选项,则可能需要默认值。例如,如果您有审计字段,则不希望在CREATED_DATE列中使用空值。但是,如果您有MIDDLE_NAME属性,则需要允许NULLS,因为不是每个人都有中间名。同样,这实际上取决于您的要求。

答案 6 :(得分:1)

开发人员提出了一个非常好的观点。作为一般规则,尽可能明确而不是依赖隐式行为是一个好主意。

我认为他/她可能是对的。如果你在列上放置默认值并且代码依赖于它,那么更改默认值可能会在以后引入难以清除的错误。

然而,与此相反的是,将默认值放在数据表本身允许您稍后更改列的默认值而无需重新编译代码。也就是说,如果编写代码的人正在思考,除非绝对必要,否则不要覆盖默认值。

答案 7 :(得分:1)

这取决于具体情况。在许多情况下,默认值可以帮助人们正确获取数据。数据输入表格通常符合模式。在数据输入表单中,可以在继续前进之前将默认值回显给用户进行验证。当默认为无意义时,这通常允许用户覆盖默认值。

但是用户界面和程序员界面是完全不同的东西。在DB中提供默认值通常是便于输入垃圾信息的一种方式。在数据库中清除垃圾信息是一项劳动密集型工作。

所以......我只会在设计规范要求时设置默认值。在这种情况下,开发人员的意见应该在设计规范中占据重要地位。

答案 8 :(得分:0)

列默认值允许程序员延迟。这不一定是坏事。

答案 9 :(得分:0)

我认为根据数据库中的默认值完全违背了防御性编程和你未来的噩梦。

答案 10 :(得分:0)

通常,不会调用默认值。如果数据有一些有意义的默认值,那么继续并在数据库中对其进行编码。但大多数数据没有默认值。名字的默认值是什么?抛出一个非null并让代码赋值。不要包含默认值,因为如果代码忘记设置名字而不是伪造的默认名字,则需要抛出错误。

我找到一个默认方便的地方是一个简单的“审计”方案。每个表都有四列:InsertedAt,InsertedBy,UpdatedAt,UpdatedBy,非空约束。使用后触发器设置值,但SQL Server将检查列是否具有值。如果没有发生约束违规,它永远不会触发。所以我添加了默认值,因为这些值不是由执行插入的代码设置的。默认值是1900年1月1日午夜和不存在的用户。触发器将检查值是否与默认值匹配,如果有人试图在插入时设置值,则抛出错误。 (另外,如果有人试图更新审计列,则更新会引发错误。)