【问题标题】:Are unique constraints on the DB necessary?对数据库的唯一约束是必要的吗?
【发布时间】:2011-04-07 07:47:55
【问题描述】:

我最近一直在想。假设我们正在使用 JSF+Spring+JPA/Hibernate(或任何其他技术)做一个 webapp,并假设我们有一个“用户”实体。我们希望用户拥有唯一的登录名。如果我们想这样做,那么我们可以在“登录”列上放置一个@UniqueConstraint,但是我们的应用程序仍然必须在用户注册期间检查用户输入是否有效(唯一),没有那个并且只有 DB 约束我们只会得到一个错误。这让我想到,数据库约束真的有必要/有用吗?我能想到的唯一两次他们会给我们带来任何好处的时候是有人试图破解我们(但我想我们的应用程序无论如何都应该是 SQL 注入证明)或者我们尝试手动更改数据库内容(这不应该真的发生了)。实际上,现在我考虑一下,数据库约束通常是必要的/良好的做法吗?比如字符串的长度等。

【问题讨论】:

  • 是否有人真的认为在假设攻击必须通过特定的不同向量 1st 的情况下让一个攻击向量完全开放是可以的?还是有人写这篇文章是为了挑衅和激发讨论?

标签: database database-design constraints unique-constraint


【解决方案1】:

是的。只需捕获密钥违规错误,密钥约束就会为您完成工作,而无需先产生额外检查的额外开销。

【讨论】:

    【解决方案2】:

    但我们的应用程序仍然需要检查 在用户注册期间是否 用户输入是否有效(唯一), 没有那个,只有数据库 约束我们将简单地得到一个 错误。

    这是我读过的最有趣的事情。你只是得到一个错误?这就是你真正需要的对吗?听说过错误捕获吗?试试 Catch 响铃吗?

    您的应用“检查”实际上会适得其反。无论如何,数据库都会检查约束,所以为什么要检查两次。该应用程序应该只插入行,就好像它会没事一样。数据库将检查唯一性并在失败时引发错误...您的应用应该捕获该错误并执行您在现有检查中所做的任何事情。

    【讨论】:

    • 好吧,我必须阅读更多内容,因为我使用的是自定义 JSF 异常处理程序,它每次捕获异常时都会将我重定向到 page_not_found.jsf 并且因为 ConstraintViolationException 是 Exception 的子类它也会被捕获并重定向到页面。不太确定我的用户会不会对此感到满意。
    • 依赖从数据库抛出的错误通常意味着您一次得到一个错误,从而导致糟糕的用户体验。如果您预先检查所有问题,您可以一次将它们全部展示给用户。
    【解决方案3】:

    如果你想有坏数据,那么就去掉数据库中的唯一约束。自 1970 年代以来,我一直在研究数据库,并查询或导入了存储在数百个数据库中的数据。我从未在应用程序级别未正确设置约束的数据库中看到好的数据。应用程序以外的许多事情都会影响数据库(从其他系统导入,快速更新产品数据以修复从查询窗口运行的数据问题,其他应用程序等)。很多时候应用程序被替换并且约束丢失了。

    【讨论】:

      【解决方案4】:

      约束,无论是唯一的还是外来的,不仅强制数据完整性,而且对性能有影响。在不了解这些“非正式”常量的情况下,数据库优化器将对如何执行语句做出不可预测的决定。

      【讨论】:

        【解决方案5】:

        通常,当您声明一组列是唯一的时,您会希望通过它进行查询 - 所以它很可能无论如何都应该被索引。

        是的,您的应用程序应该进行适当的检查,但是如果出现错误怎么办?如果您的数据库知道某些东西是唯一的,那么至少您知道您不会存储无效数据(或者不是“严重”的无效数据,例如旨在唯一的数据副本)。无论如何,你可以问相反的问题:你花了多少钱?

        【讨论】:

          【解决方案6】:

          我认为数据人员会说两者都是绝对必要的。您的问题假设您的中间层应用程序代码现在和永远都在该数据库前面。

          事实上,中间层应用程序来来去去,但数据永远存在。

          在架构设计中,列的长度是不可避免的。我想你是在问中间层执行它们是否是一个好习惯。也许不是,但它们是数据库的关键。

          【讨论】:

            【解决方案7】:

            是的,他们是。他们在最低级别强制执行数据完整性。

            您可能希望手动更改数据库内容(即升级到新版本)

            您可能忘记检查代码中的某些约束。

            您可以将其视为客户端/服务器验证。您的程序是客户端,数据库是服务器。大多数情况下客户端验证就足够了,但您必须进行服务器验证以防万一出现问题。

            【讨论】:

              【解决方案8】:

              对我来说,绝对是的,请参阅 97 Thinks Every Software Architect 应该知道的 Dan Chak 的 Database as a Fotress。他说得比我好得多。

              【讨论】:

              • 书很不错,虽然里面所有的文章都是开源的,所以你可以在那个wiki上免费阅读
              猜你喜欢
              • 2013-05-21
              • 2019-10-10
              • 2010-12-13
              • 2017-02-15
              • 2016-09-05
              • 1970-01-01
              • 2021-09-04
              • 2011-02-05
              • 2016-05-01
              相关资源
              最近更新 更多