介绍其实这个话题是老生常谈了,很多人在工作中确实不知道如何使用外键。阿里的JAVA规范中包含如下内容[强制]不使用外键和级联,所有外键概念必须在应用层解决。但是,当我问他们为什么的时候,他们大多回答说每次做DELETE或者UPDATE的时候都要考虑外键约束,这会造成开发的痛苦,测试数据也极其不方便。坦率地说,这也是事实。不过不够全面,所以开篇文章详细讲解一下。首先要明确一点,外键约束是约束。这种约束的存在将保证表之间的数据关系“永远完整”。因此,外键约束的存在并非完全没有优势。例如,使用外键可以保证数据的完整性和一致性。级联操作方便。将数据完整性判断委托给数据库,减少了程序的代码量。但是,你不能两者兼得。外键可以保证数据的完整性,但是会给系统带来很多缺陷。正是因为这些缺陷,我们不推荐使用外键,如下:性能问题假设一个表名为user_tb。那么这张表中有两个外键字段,分别指向两个表。那么每次向user_tb表插入数据时,都要查询这两个外键对应的表中是否有相应的数据。如果由程序来控制,这个查询过程就可以控制在我们手中,可以省略一些不必要的查询过程。但是如果是数据库控制的,就需要在这两个表中进行判断。并发问题在使用外键的情况下,每次修改数据都需要去另外一张表查看数据,需要额外获取锁。在高并发、大流量的事务场景下,使用外键更容易造成死锁。这里的扩展性问题主要分为两点方便平台迁移。比如你从Mysql迁移到Oracle,触发器、外键之类的东西可以利用框架本身的特性来实现,而不是依赖于数据库本身。特性,做迁移更方便。方便分库分表。在水平拆分和分库的情况下,外键不能生效。将数据之间关系的维护放到应用程序中,为以后的分库分表省去很多麻烦。技术问题使用外键实际上是将应用程序应该执行的判断逻辑传递给了数据库。那么这意味着数据库的性能开销变大了,这对DBA有更高的要求。很多中小型公司因为资金问题没有聘请专业的DBA,所以选择不使用外键来减少数据库消耗。反之,如果约束逻辑在应用程序中,发现应用服务器性能不足,则可以通过增加机器进行水平扩展。如果是在数据库服务器上,数据库服务器会成为性能瓶颈,难以水平扩展。
