大厂为啥不用“外键”?!

大家在学习数据库的过程中一定都接触过外键这个概念,并且在各种课后习题中外键还是一个非常重要的考察内容,但是在实际的企业开发过程中,你会发现外键是被严格禁止使用的,当需要多个表之间进行关联时,做法是冗余相关字段,而不是建立外键。

为什么?

什么是外键?
两张表有关联关系,才会涉及外键的概念。举个例子,有两张表;

1)学生表(学生 id、学生姓名)

CREATE TABLE student (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘学生id’,
name varchar(256) NOT NULL COMMENT ‘学生姓名’,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘学生表’;
2)成绩表(成绩 id、学生 id,分数),对于成绩表来说,学生 id 就是外键

CREATE TABLE score (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘成绩 id’,
student_id bigint(20) unsigned NOT NULL COMMENT ‘学生id’,
score int(20) unsigned NOT NULL COMMENT ‘分数’
PRIMARY KEY (id),
KEY student_id (student_id),
CONSTRAINT fk_student_id FOREIGN KEY (student_id) REFERENCES student (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘成绩表’;
如上,我们通过 foreign key … references … 来定义外键,将当前表的字段关联到另一张表的某个字段。

外键和主键一样,都是一种约束,外键约束也称为引用约束或引用完整性约束):

外键列必须引用另一个表中的主键或唯一键列
外键列必须满足引用完整性,也就是说,它们包含的值必须存在于被引用表的主键或唯一键列中
通俗来说:

成绩表插入数据时,student_id 必须是学生表已存在的 id
学生表删除/更新数据时,会自动删除/更新成绩表中引用 student.id 的数据(级联)
为什么不推荐使用外键?
阿里的开发手册中提到:

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

定义外键之后,数据库的每次操作都需要去检查外键约束。对于插入来说,影响了插入速度;对于更新来说,级联更新是强阻塞,存在数据库更新风暴(Database Update Storm)的风险。

所谓 Database Update Storm,指的是在高并发环境下,多个客户端同时对数据库进行大量的更新操作,存在锁竞争问题甚至死锁,从而导致数据库性能急剧下降或完全崩溃。

另外,当数据量非常大的时候,常见手段是分库分表,但外键通常难以跨越不同数据库来建立联系,数据的一致性更难维护。

因此,外键与级联并不适合分布式、高并发集群,但单机低并发业务可以考虑使用外键保证一致性和完整性。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数字天下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值