凭什么不让使用外键!?你知道吗?
创始人
2025-07-05 19:41:21
0

MySQL 外键(Foreign Key)是用于建立表之间关系的,它定义了一个表中的一列或一组列,这些列的值必须在另一个表的主键列中存在。

MySQL 外键最大的作用就是有助于维护数据的一致性和完整性。

  • 一致性:如果一个订单表引用了一个客户表的外键,外键可以确保订单的客户 ID 存在于客户表中,从而保持数据的一致性。
  • 完整性:外键可以防止在引用表中删除正在被其他表引用的记录,从而维护数据的完整性。

但是,其实在很多大型互联网公司中,很少用外键的,甚至阿里巴巴Java开发手册中明确规定了:

【强制】不得使用外键与级联,一切外键概念必须在应用层解决。 

说明: 以学生和成绩的关系为例,学生表中的 student_id 是主键,那么成绩表中的 student_id 则为外键。如果更新学生表中的 student_id,同时触发成绩表中的 student_id 更新,即为级联更新。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。

那么,使用外键会带来哪些问题呢?(另外我出了一份Java面试宝典,里面有800多道面试常考题目)

先举个例子,我们有两张表:Orders(订单)和 OrderItems(订单项)。这两个表之间通过外键建立关系,订单项表中的外键引用订单表的订单号。

CREATE TABLE Orders (
    OrderID INT PRIMARY KEY,
    CustomerID INT,
    OrderDate DATE,
    -- 其他订单信息
);

CREATE TABLE OrderItems (
    ItemID INT PRIMARY KEY,
    OrderID INT,
    ProductID INT,
    Quantity INT,
    -- 其他订单项信息
    FOREIGN KEY (OrderID) REFERENCES Orders(OrderID)
);

性能问题

首先就是性能问题,因为外键会增加数据库的维护负担,因为每次插入、更新或删除数据时,数据库都需要检查外键约束的完整性。

这两张表中共有两个索引,一个是Orders表的主键索引,一个是OrdersItems表的外键索引,这就使得每次插入、更新或删除订单或订单项时,数据库需都要维护这两个索引,这可能会导致性能开销。

其次,在插入新的订单项之前,数据库需要执行数据一致性检查以确保引用的订单号在 Orders 表中存在。这额外的检查可能增加插入订单项的执行时间。

锁竞争问题

还有就是比较容易忽略的锁竞争问题。当多个事务同时尝试插入或更新订单项时,它们就需要去检查订单表,就需要获得额外的锁,以确保一致性。这可能导致事务之间的锁竞争,降低并发性能。(另外我出了一份Java面试宝典,里面有800多道面试常考题目)

一旦有了锁竞争,就可能带来更加严重的死锁问题,所以都是需要尽量避免的。

Merge无法适应分库分表

当数据量打的时候,我们就要考虑分库分表了,但是在分库分表环境中,相关数据可能分布在不同的数据库中,外键通常难以跨越不同数据库来建立关系。更重要的是,分库分表环境中,数据的一致性可能更难维护。跨库事务搞不定。

以上,就是一些比较重要的原因吧。其实最主要的还是外键约束会带来一些额外的开销及锁竞争。而在很多大型互联网公司中,都是会尽量避免的。

就像大厂会使用RC来替代RR一样,会尽可能的降低锁的发生,一方面提升性能,一方面避免死锁。

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
30分钟搞定iOS自定义相机 最近公司的项目中用到了相机,由于不用系统的相机,UI给的相机切图,必须自定义才可以。就花时间简单研究...
Intel将Moblin社区控... 本周二,非营利机构Linux基金会宣布,他们将担负起Moblin社区的管理工作,而这之前,Mobli...