最近比较好奇在看阿里的Java开发规范时发现阿里不建议使用外键约束,有大佬可以讲一下为什么不建议用吗?
先说结论,不太认可。
首先这世界上有那么多编程规范,有谷歌的、airbnb 的、amazon 的、netflix 的、京东的、阿里的,字节跳动的,这里面有大量内容,你应该选择你需要的东西进行参考而不是把谁家的捧为「圣经」
对于关系型数据库来说,最重要的就是关系的表达。如果不使用物理外键,这个关系要如何表达?很多开发者说:「用了物理外键就要去维护数据一致性,不能随便删除数据」。这里的道理很简单,就像开汽车。汽车公司为了安全给你设计了安全带,但是你觉得绑安全带太麻烦,不想用。那就只能接受不安全的结果。
关系型数据的一致性保证,是数据库厂商费了好大的劲实现出来,帮你保证数据一致安全的强有力保证。放着这么好的东西不用,跑去应用层上做处理,甚至还用分布式锁来解决某些问题,这是一种本末倒置。
对于物理外键,我们不仅要用,而且要常用。
在某些非常特殊的状况,是不太推荐使用物理外键。但是讨论那种极端的例子没有意义。你写的是应用程序不是从他诞生的那一刻起,就要上外太空飞船上面运行的。
架构是逐步演进的,等到了那个时候自然会知道怎么办。不要一开始就去想如何殖民月球的问题。
最后,现代 Java 技术栈可以参考:
https://segmentfault.com/a/1190000046017562
这一套,里面有真正的现代 JVM 编程应该使用的编程范式和技术栈,如果你喜欢,欢迎加群大家一起交流技术。
可以参考这篇文章:开发规范中为什么要禁用外键约束
总结以下几点
因此,阿里巴巴建议在应用层面处理数据的一致性和完整性,而不是依赖数据库的外键约束。
补充
性能问题例子
假设有一个电商平台,订单表(orders)和订单详情表(order_details)之间有外键约束。每次插入一个新订单时,数据库需要检查订单详情表中的外键约束,确保订单ID存在于订单表中。如果每天有成千上万的订单,这些检查会显著增加数据库的负担,导致性能下降。
并发问题例子
在一个社交媒体应用中,用户表(users)和帖子表(posts)之间有外键约束。当大量用户同时发布帖子时,数据库需要对用户表进行行级锁定以确保外键约束的完整性。这会导致其他用户的写操作被阻塞,影响系统的并发性能。
级联删除问题例子
在一个学校管理系统中,班级表(classes)和学生表(students)之间有外键约束,并设置了级联删除。如果删除一个班级记录,所有属于该班级的学生记录也会被删除。这可能会导致误操作引发大量数据丢失,难以恢复。
数据迁移和耦合问题例子
在一个企业管理系统中,员工表(employees)和部门表(departments)之间有外键约束。如果企业决定将数据迁移到一个新的数据库系统,必须先解除这些外键约束,否则迁移过程会非常复杂且容易出错。
测试和开发不便例子
在开发一个库存管理系统时,商品表(products)和库存表(inventory)之间有外键约束。为了测试某些功能,开发人员需要插入大量测试数据。如果有外键约束,插入数据的顺序和完整性要求会增加测试数据准备的复杂性,影响开发效率。