阿里巴巴Java开发规范为何不建议使用外键约束?

最近比较好奇在看阿里的Java开发规范时发现阿里不建议使用外键约束,有大佬可以讲一下为什么不建议用吗?

阅读 992
2 个回答

可以参考这篇文章:开发规范中为什么要禁用外键约束

总结以下几点

  1. 性能问题:外键约束会增加数据库的负担,因为每次插入、更新或删除操作都需要进行额外的外键检查。这会导致性能下降,特别是在高并发的场景下。
  2. 并发问题:外键约束会引入行级锁,导致主表写入时可能会被阻塞,从而影响系统的并发性能。
  3. 级联删除问题:多层级联删除可能会导致数据变得不可控。例如,删除一个主表记录时,所有相关的从表记录也会被删除,这可能会引发数据丢失。
  4. 数据迁移和耦合问题:外键约束会导致数据库表之间的耦合度增加,数据迁移和维护变得更加困难。如果需要将数据迁移到其他数据库系统,必须先解除外键约束。
  5. 测试和开发不便:在开发和测试过程中,外键约束会增加复杂性,导致测试数据的准备和维护变得更加困难。

因此,阿里巴巴建议在应用层面处理数据的一致性和完整性,而不是依赖数据库的外键约束。

补充

性能问题例子

假设有一个电商平台,订单表(orders)和订单详情表(order_details)之间有外键约束。每次插入一个新订单时,数据库需要检查订单详情表中的外键约束,确保订单ID存在于订单表中。如果每天有成千上万的订单,这些检查会显著增加数据库的负担,导致性能下降。

并发问题例子

在一个社交媒体应用中,用户表(users)和帖子表(posts)之间有外键约束。当大量用户同时发布帖子时,数据库需要对用户表进行行级锁定以确保外键约束的完整性。这会导致其他用户的写操作被阻塞,影响系统的并发性能。

级联删除问题例子

在一个学校管理系统中,班级表(classes)和学生表(students)之间有外键约束,并设置了级联删除。如果删除一个班级记录,所有属于该班级的学生记录也会被删除。这可能会导致误操作引发大量数据丢失,难以恢复。

数据迁移和耦合问题例子

在一个企业管理系统中,员工表(employees)和部门表(departments)之间有外键约束。如果企业决定将数据迁移到一个新的数据库系统,必须先解除这些外键约束,否则迁移过程会非常复杂且容易出错。

测试和开发不便例子

在开发一个库存管理系统时,商品表(products)和库存表(inventory)之间有外键约束。为了测试某些功能,开发人员需要插入大量测试数据。如果有外键约束,插入数据的顺序和完整性要求会增加测试数据准备的复杂性,影响开发效率。

先说结论,不太认可。

首先这世界上有那么多编程规范,有谷歌的、airbnb 的、amazon 的、netflix 的、京东的、阿里的,字节跳动的,这里面有大量内容,你应该选择你需要的东西进行参考而不是把谁家的捧为「圣经」

对于关系型数据库来说,最重要的就是关系的表达。如果不使用物理外键,这个关系要如何表达?很多开发者说:「用了物理外键就要去维护数据一致性,不能随便删除数据」。这里的道理很简单,就像开汽车。汽车公司为了安全给你设计了安全带,但是你觉得绑安全带太麻烦,不想用。那就只能接受不安全的结果。

关系型数据的一致性保证,是数据库厂商费了好大的劲实现出来,帮你保证数据一致安全的强有力保证。放着这么好的东西不用,跑去应用层上做处理,甚至还用分布式锁来解决某些问题,这是一种本末倒置。

对于物理外键,我们不仅要用,而且要常用。

在某些非常特殊的状况,是不太推荐使用物理外键。但是讨论那种极端的例子没有意义。你写的是应用程序不是从他诞生的那一刻起,就要上外太空飞船上面运行的。

架构是逐步演进的,等到了那个时候自然会知道怎么办。不要一开始就去想如何殖民月球的问题。

最后,现代 Java 技术栈可以参考:
https://segmentfault.com/a/1190000046017562
这一套,里面有真正的现代 JVM 编程应该使用的编程范式和技术栈,如果你喜欢,欢迎加群大家一起交流技术。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏