网站首页 > 技术文章 正文
以下文章来源于飞天小牛肉 ,作者小牛肉
如有侵权,联系删除
什么是外键?
两张表有关联关系,才会涉及外键的概念。举个例子,有两张表;
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,指的是在高并发环境下,多个客户端同时对数据库进行大量的更新操作,存在锁竞争问题甚至死锁,从而导致数据库性能急剧下降或完全崩溃。
另外,当数据量非常大的时候,常见手段是分库分表,但外键通常难以跨越不同数据库来建立联系,数据的一致性更难维护。
因此,外键与级联并不适合分布式、高并发集群,但单机低并发业务可以考虑使用外键保证一致性和完整性。
猜你喜欢
- 2025-09-09 count(*)、count1(1)、count(主键)、count(字段) 哪个更快?
- 2025-09-09 深入探索 Spring Boot3 中 MyBatis 的 association 标签用法
- 2025-07-02 mysql count(1)、count(*) 与 count (列名) 的执行区别
- 2025-07-02 非DBA原来是这样设计关系数据表的
- 2025-07-02 高并发下实现幂等的几种方式(高并发如何解决方案)
- 2025-07-02 [JPA教程]02.认识JPA的注解.md(jpa的@query注解)
- 2025-07-02 MYSQL存储引擎InnoDB(二):使用注意点
- 2025-07-02 MySQL数据库最常用操作(mysql常见操作)
- 2025-07-02 表格存储 SQL 查询多元索引(表格存储 sql 查询多元索引信息)
- 2025-07-02 雪花算法(雪花算法使用)
- 最近发表
-
- count(*)、count1(1)、count(主键)、count(字段) 哪个更快?
- 深入探索 Spring Boot3 中 MyBatis 的 association 标签用法
- js异步操作 Promise fetch API 带来的网络请求变革—仙盟创梦IDE
- HTTP状态码超详细说明_http 状态码有哪些
- 聊聊跨域的原理与解决方法_跨域解决方案及原理
- 告别懵圈!产品新人的接口文档轻松入门指南
- 在Javaweb中实现发送简单邮件_java web发布
- 优化必备基础:Oracle中常见的三种表连接方式
- Oracle常用工具使用 - AWR_oracle工具有哪些
- 搭载USB 3.1接口:msi 微星 发布 990FXA Gaming 游戏主板
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)