欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

为什么实际开发中不使用外键

程序员文章站 2022-03-23 19:03:25
背景上学的时候,大家肯定都学习了数据库相关的课程,MySQL和Oracle中都有外键。但是自从开始工作,我就发现一个奇怪的问题,企业实际开发中,表结构定义都不会用数据库的外键,当需要用外键做关联的时候,也是仅对字段进行冗余存储,不会用foreign key的定义,究竟有哪些考量呢?此篇做个总结。外键什么是外键两张表有关联关系,才会涉及外键的概念。举例 商品表(商品id、商品名称),订单表(订单id、商品id)。对于订单表来说,商品id就是外键。外键的作用CREATE TABLE `...

背景

上学的时候,大家肯定都学习了数据库相关的课程,MySQL和Oracle中都有外键。但是自从开始工作,我就发现一个奇怪的问题,企业实际开发中,表结构定义都不会用数据库的外键,当需要用外键做关联的时候,也是仅对字段进行冗余存储,不会用foreign key的定义,究竟有哪些考量呢?此篇做个总结。

外键

什么是外键

两张表有关联关系,才会涉及外键的概念。举例 商品表(商品id、商品名称),订单表(订单id、商品id)。对于订单表来说,商品id就是外键。

外键的作用

CREATE TABLE `commodity` (
  `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='商品表';
CREATE TABLE `order` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '订单id',
  `commodity_id` bigint(20) unsigned NOT NULL COMMENT '商品id',
  PRIMARY KEY (`id`),
  KEY `commodity_id` (`commodity_id`),
  CONSTRAINT `fk_commodity_id` FOREIGN KEY (`commodity_id`) REFERENCES `commodity` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';

1. 当我们使用foreign key定义时,会发生什么呢?

  • order表insert数据时,commodity_id必须是commodity已存在的id
  • commodity表delete数据时,要先删除order表中引用commodity.id的数据

2. 外键有啥作用呢?官方说法是,外键可以保证数据的完整性和一致性。 如何保证呢?——级联

删除commodity表数据时,会自动删除order表的关联数据


为什么不用外键

先来瞧瞧阿里的开发手册怎么说:

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

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

其他大佬的看法:

  • 业务数据生成顺序,未必一定可以先生成外键的值,再生成明细数据
  • 修数据:应该没有人没修过生产环境的数据吧?有外键约束,修数据就有一些麻烦了
  • 性能和扩展问题:级联控制,在应用层面做,可以降低数据库的压力。因为数据库的资源是有限资源,应用资源是可以通过加机器进行水平扩展的
  • 分库分表的场景,无法使用外键

为什么实际开发中不使用外键

为什么实际开发中不使用外键

参考

mysql foreign key(外键) 说明与实例

mysql 外键(foreign key)的详解和实例

外键约束

数据库(外键及其约束理解)

【原创】数据库中为什么不推荐使用外键约束

是否有必要使用外键?为什么不用外键?

本文地址:https://blog.csdn.net/yxz8102/article/details/107303975