在数据库中使用默认值是不好的做法吗?

时间:2009-11-09 15:20:11

标签: database-design

代码不应该处理默认值而不是数据库吗?

10 个答案:

答案 0 :(得分:18)

您在数据库中可以执行的任何操作通常都更加强大。如果您处理默认值,如果仅在您的应用中未指定任何值,则会使用默认值,并且有人设法通过您的应用程序以其他方式连接到您的数据库(并相信我 - 用户尝试使用Excel或其他工具进行连接) - 然后数据库大开,用户可能会插入糟糕的数据。

参照完整性和检查约束也是如此。我相信如果你试图在数据库中拥有尽可能多的约束,你会更好 - 那么无论用户如何连接,如果他没有向你发送任何东西,你可以放入合理的默认值。

不要让应用程序处理您的检查 - 将其留给数据库!

另外,如果您不必指定所有“明显”的默认值,例如“LastChangedOn”日期列等的“getdate()”,它会使您的SQL插入语句更精简和更精简。

答案 1 :(得分:4)

这取决于您对“默认”值的看法。可以这样想:如果更改默认设置会发生什么?如果应更新现有值,则默认值应仅在程序代码中,但如果现有值应保留,则应将默认值存储在数据库中。

答案 2 :(得分:4)

代码默认值更易于单元测试。

代码默认值支持多种方案。数据库列默认值是一个适合所有人。例如,DB列的默认值可能因客户类型而异。

DB列默认值对于维护开发人员来说通常是不透明的,因为它们远离INSERT语句,INSERT语句通常位于中间层代码,存储过程等中。无论是哪种方式,默认值的存在与否都会令人惊讶。

数据库列默认为数据库保护数据库,使客户端懒得完全填写默认值,这是一种数据损坏。

客户端开发人员可以破坏这两种默认值。在中间层使用有缺陷的默认值为开发人员设置障碍更容易。 AFAIK,没有数据库允许您要求字段采用INSERT的默认值。 (编辑:TRIGGER可以强制执行此操作,但您必须将默认值复制到触发器,TRIGGER将使用默认值覆盖任何插入的值)这可能很重要的一个示例是人们用于未知但未来的各种令牌日期,或者未知但过去的日期,或者如果他们使用包含时间的GETDATE()或者他们使用包含年,月,日和没有时间的默认日期则可能很重要。

我建议确保默认值存在于数据库中有意义的地方,但实际上并不使用它们。数据库默认值应该是最后的默认值,默认值应该稳固在中间层(即存储过程,数据访问层)。 DB列默认值就像一个异常处理程序 - 当某人意外忘记提供值时,应使用什么值来防止数据损坏?

答案 3 :(得分:3)

我通常认为代码应该处理默认值。这将有助于保持您的数据库精益和意味着。虽然,如果您的数据库中有太多空字段,您可能需要重新考虑设计。

实施例

想象一下,你有一个包含一百万或更多行的表。在此表中,您有一个datetime列,可能在5%的时间内填充。随着时间的推移,通过存储NULL默认值来节省的空间量将使得必要的默认检查更有价值。

答案 4 :(得分:3)

恰恰相反。数据库应始终提供默认值,以确保添加的记录有效且有意义。请记住,在编写应用程序时,您无法预测哪些代码最终会将记录添加到数据库中。

这并不是说您可能没有应用程序指定的第二级默认数据,这取决于创建数据时的应用程序状态。

因此,假设您的员工状态代码可以是“P”(预期),“A”(有效),“T”(已终止)或“R”(已退休)。您应该在数据库级别指定人们是否以“P”或“A”进入系统(或者可能是未分配的第五个代码)。但是,您的应用程序可以而且应该要求用户创建员工记录,以从(例如)一组单选按钮中选择一个选项,并在插入记录时使用该值。

答案 5 :(得分:2)

与大多数“代码与数据库”参数一样,它取决于。

如果您的数据库(或表)将被许多不同的客户(即不能紧密合作的团队)访问,那么数据库应该保护自己。理想情况下,一切都应该通过存储过程来完成。

如果单个应用程序可以访问数据库,则该应用程序可以包含业务逻辑。在这种情况下,一切都应该由一个应用程序完成,并且该应用程序访问数据库。

另外:如果您想要一个便宜的答案 - 请询问负责指定(和记录)您的数据模型的人。如果你没有,开始恐慌。

答案 6 :(得分:1)

您可能需要考虑更改默认值所需的内容。如果您的应用程序在内部,可能不难更改,但如果它在您的客户站点上,那么对数据库进行更改可能是一个非常困难的过程。如果您有数百或数千个客户端,并且您需要说服他们的DBA为您提供对数据库的更新过程SA访问权限,那么您将遗憾地将任何应用程序逻辑放入数据库中(包括默认值)。

答案 7 :(得分:1)

如果您担心数据完整性(如果您不是为什么拥有数据库?),则需要数据库中的默认值。仅在代码中执行此操作是不负责任的。数据从应用程序代码以外的其他来源进入数据库。

答案 8 :(得分:1)

数据库旨在记录事实断言。

为了让用户做出不完整的断言并让dbms对不完整的部分做出沉默的假设,这很简单。

如果您想要可以长时间保持使用的强大,可靠的系统,那么不要让该系统的任何部分对用户不说的内容做出假设。

处理演示级别的默认值,而不是其他地方。并以这样一种方式处理它们:用户无法看到他提交的数据(所有数据!)。

答案 9 :(得分:1)

除非价值与您的业务逻辑完全脱钩,否则我会说是的,这是不好的做法。至少根据分层模型,业务层与数据层分开。

请记住:
- 在列上设置默认值并不能保证数据的完整性(应用程序应该能够处理列中的任何值)
- 以某种方式在数据库中复制业务逻辑的麻烦和费用并不能保证数据的完整性。

最理智的数据库安全方法就是拥有 - 数据库安全性。例如,如果恶意用户设法破坏了该安全层,那么无论数据限制如何,您的数据都不会有机会。