为什么实际开发中不使用外键
程序员文章站
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 更新,即为级联更新。外键与级 联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风 险;外键影响数据库的插入速度。
其他大佬的看法:
- 业务数据生成顺序,未必一定可以先生成外键的值,再生成明细数据
- 修数据:应该没有人没修过生产环境的数据吧?有外键约束,修数据就有一些麻烦了
- 性能和扩展问题:级联控制,在应用层面做,可以降低数据库的压力。因为数据库的资源是有限资源,应用资源是可以通过加机器进行水平扩展的
- 分库分表的场景,无法使用外键
参考
本文地址:https://blog.csdn.net/yxz8102/article/details/107303975
下一篇: 了解mybatis