我最近一直在想。假设我们正在使用 JSF+Spring+JPA/Hibernate(或任何其他技术)做一个 webapp,并假设我们有一个“用户”实体。我们希望用户拥有唯一的登录名。如果我们想这样做,那么我们可以在“登录”列上放置一个@UniqueConstraint,但我们的应用程序仍然必须在用户注册期间检查用户输入是否有效(唯一),没有那个并且只有 DB 约束我们只会得到一个错误。这让我想到,数据库约束真的有必要/有用吗?我能想到的唯一两次他们会给我们带来任何好处的时候是有人试图破解我们(但我想我们的应用程序无论如何都应该是 SQL 注入证明)或者我们尝试手动更改数据库内容(这不应该真的发生了)。其实现在想想,数据库约束通常是必要的/良好的做法吗?比如字符串的长度等等。
8 回答
对我来说,绝对是的,请参阅Dan Chak 的Database as a Fortress,来自97 Thinks Every Software Architect Should Know。他说得比我好得多。
对,他们是。他们在最低级别强制执行数据完整性。
您可能想要手动更改数据库内容(即升级到新版本)
您可能会忘记检查代码中的某些约束。
您可以将其视为客户端/服务器验证。您的程序是客户端,数据库是服务器。大多数情况下客户端验证就足够了,但您必须进行服务器验证以防万一出现问题。
我认为数据人员会说两者都是绝对必要的。您的问题假设您的中间层应用程序代码现在和永远都在该数据库前面。
事实是,中间层应用程序来来去去,但数据永远存在。
在模式设计中没有摆脱列的长度。我认为您是在问中间层执行它们是否是一种好习惯。也许不是,但它们是数据库的关键。
如果您想拥有不良数据,请取消数据库中的唯一约束。自 1970 年代以来,我一直在研究数据库,并查询或导入了存储在数百个数据库中的数据。我从未在应用程序级别未正确设置约束的数据库中看到好的数据。应用程序以外的许多事情都会影响数据库(从其他系统导入,快速更新产品数据以修复从查询窗口运行的数据问题,其他应用程序等)。很多时候应用程序被替换并且约束丢失了。
通常,当您声明一组列是唯一的时,您会希望通过它来查询它 - 所以它很可能无论如何都应该被索引。
是的,您的应用程序应该进行适当的检查,但是如果出现错误怎么办?如果您的数据库知道某些东西是唯一的,那么至少您知道您不会存储无效数据(或者不是“严重”的无效数据,例如旨在唯一的数据的重复)。无论如何,你可以问相反的问题:你花了多少钱?
是的。只需捕获密钥违规错误,密钥约束就会为您完成工作,而无需先进行额外检查的额外开销。
独特的和外来的约束不仅强制数据完整性,而且对性能有影响。在不了解这些“非正式”常量的情况下,数据库优化器将对如何执行语句做出不可预测的决定。
但是我们的应用程序仍然必须在用户注册期间检查用户输入是否有效(唯一),没有它并且只有使用 DB 约束,我们只会得到一个错误。
这是我读过的最有趣的事情。你只是得到一个错误?这就是你真正需要的对吗?听说过错误捕获吗?尝试 Catch 响铃?
你的应用程序“检查”实际上是非常适得其反的。无论如何,数据库都会检查约束,所以为什么要检查两次。该应用程序应该只插入行,就好像它会没事一样。数据库将检查唯一性并在失败时引发错误......您的应用程序应该捕获该错误并执行您在现有检查中所做的任何事情。