前段时间我和同事们讨论了关于坚持的问题。 领域模型 以及我们是否应该在数据库级别强制执行外键约束。

我的第一反应是,关系数据库的使用本身就意味着强制执行此类约束,但有些人认为数据库应该被视为只是一种持久性机制,因此我们应该避免在其中放置任何业务逻辑。我们最终没有使用外键约束。

这是我的问题(我希望它不是太笼统):在这些情况下实施关键约束是否被认为是良好做法?

有帮助吗?

解决方案

实施约束,但不要在你的工作中依赖它们 商业逻辑

  • 商业 数据库逻辑:我同意这个原则。如果你的 非SQL 业务代码 依靠 对数据库的约束来检查你的数据库一致性,那么你应该重新考虑你的业务逻辑。
  • 有数据库约束并没有什么问题 此外 到你的业务逻辑。特别是因为像外键引用完整性和其他 UNIQUE 约束这样的事情很容易做到,而且 RDBMS 可以非常高效地为您完成这项工作,而无需太多维护。
  • 你不会用吗 指数 也在数据库上,因为它不是 纯粹 持久性相关?
  • 查找并修复软件错误可能会花费您一些时间,但是您 确实 不想花费更多时间清理或(更糟糕)丢失一些数据,只是因为您省去了为 FK 编写一行脚本的麻烦。真的吗:你在这里免费得到一些东西然后你拒绝它?
  • [编辑1]: 你能保证你的数据库中的数据会被管理吗 仅有的 通过您的应用程序?似乎总是有例外,主要是高级用户,他们有时(很少:-)会犯错误并执行一些 SQL 语句来清理代码、更新状态(由于拼写错误而更新为无效值)等。
  • [编辑2]: 建筑 领域驱动 模型并不是不聘请优秀数据库管理员的借口。使用 ORM 并不是不雇用优秀数据库开发人员的借口。

但如果你和你的团队能够写 无错误的软件 并处理代码中所有可能的异常情况(包括硬件/网络/虚拟用户/程序员错误故障),然后“嘿,为什么要麻烦 多余的 FK 限制...." - -预告片-

其他提示

我是这么认为的,我认为这是没有那么多的东西业务逻辑,但防止被输入到数据库中“坏”数据。一旦数据库变得非常大这些约束将防止头痛的未来。

这将尤其生效,当你有多个开发人员开发针对相同的数据的应用程序。这将确保他们也只能输入有效的数据。具有约束在X程序控制,而不是1点是肯定有益的。

我觉得自己像一个纯粹的开发方法的缘故忽略了真正有用的工具(数据库级数据的完整性)是适得其反。数据库是在这种事情真的很棒......让他们做到这一点。

在某些时候,每一个方法开始分解,你就必须是实用的。

我也是这么认为的,但自从我开始写了很多面向资源的系统我看来已经改变。通常情况下,远不止外键约束必须验证一个数据 - 例如,“分配”一票是在状态必须有一个有效的“assigned_to”值,依此类推。所有这些规则必须被存放在某种形式的验证例程,虽然理论上它可能不是的伤害的有额外的验证在数据库级别,如果您的应用程序级的验证工作,检查外国键约束只是浪费周期。更糟糕的,但是,你现在得到的逻辑大约在两个地方重复你的数据模型 - 验证代码和数据库的限制。

想想这样说:你想在移动其他任何应用程序逻辑的数据库(例如,通过存储过程),如果你不就得了?如果你不是被迫性能考虑这样做,我认为答案一般应是“不”。

“我的第一反应是,非常使用关系型数据库的暗示这种约束的强制执行,但一些人认为,数据库应被视为只是一个持久性机制,因此,我们应避免将任何业务逻辑在里面。我们结束了不使用外键约束。“

是的,好了,平庸的大多数总是赢的数字仅仅是力的那种辩论,唉。

如果您仍想打那场战役,你可能会问你的对手,他们是如何打算让任何人使用“直接数据库编辑器”(ALA DB2援助,SPUFI,...),以及它们如何打算让任何人破坏使用这种工具的数据库(其通过定义绕过其编程业务约束)。

如果你想跟着领域驱动设计范例,那么答案是肯定的一个聚集中任何东西,也没有任何的交叉聚合链接。

在几乎所有情况下,你想级联删除当根本身被删除,因此具有代表这个外键下的聚合根东西被删除,使您可以在数据库级别实现这一目标。你也可以有你的资料库做级联删除自己,如果你不想在数据库级别做,但问题依然是总结孩子不应该在没有根存在。

有关跨聚合的关注,你可能会与业务决策处理,以当一个或另一个被删除会发生什么。通常你会想对付这种异步允许的可扩展性,所以你的域模型最终被最终一致。因此,它是没有意义的在这些情况下执行外键就会有一个时间窗口,其中一个或另一个键可能不存在。

希望帮助!而对于更多的信息,明确检查出埃文斯的书领域驱动设计 - 和纸幅围绕所述许多链路太

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top