良许Linux教程网 干货合集 大厂为啥不用“外键”?!

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

在学习数据库时,大家都会接触到外键的概念,并且在各种课后习题中,外键都是一个重要的考察内容。然而,在实际的企业开发中,外键却通常被严格禁止使用。相反,当需要对多个表进行关联时,通常会选择冗余相关字段的方法,而不是建立外键。

这种做法的原因是什么呢?

外键的概念

外键是两个表之间的关联关系的一种体现。举个例子,考虑两个表:

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 ... 来定义外键,将当前表的字段关联到另一张表的某个字段。

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

  1. 外键列必须引用另一个表中的主键或唯一键列;
  2. 外键列必须满足引用完整性,也就是说,它们包含的值必须存在于被引用表的主键或唯一键列中。

通俗来说:

  1. 成绩表插入数据时,student_id 必须是学生表已存在的 id;
  2. 学生表删除/更新数据时,会自动删除/更新成绩表中引用 student.id 的数据(级联)。

为什么不推荐使用外键?

阿里的开发手册中提到:

 

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

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

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

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

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

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部