大厂的MySQL为啥不用外键?! 大厂的mysql为啥不用外键接口
wptr33 2024-12-28 15:58 18 浏览
背景
以前工作学习中,一直被告诫不要使用外键,所以也没有仔细整理过。
这里记录一下笔记。
外键
是什么?
MySQL 的外键(Foreign Key)是一种关系型数据库中用于建立表与表之间关联关系的重要工具。
外键定义了两个表之间的引用关系,它连接了两个表,使它们之间建立起一定的联系。
外键用于维护表与表之间的一致性和完整性,确保数据的准确性和可靠性。
如何定义
在创建表时,可以使用 FOREIGN KEY 关键字来定义外键。外键通常与 REFERENCES 关键字一起使用,用于指定引用的表和列。
外键通常关联到另一个表的主键列,这样它就能确保引用的数据是一致的。
CREATE TABLE 表名 (
列1 数据类型,
列2 数据类型,
...
FOREIGN KEY (外键列) REFERENCES 关联表名(关联列)
);
级联操作
外键还可以定义级联操作,包括 CASCADE、SET NULL、SET DEFAULT 和 NO ACTION。
这些操作定义了在主表中进行更新或删除操作时,对应的外键列在从表中的行的处理方式。
例如,CASCADE 表示主表的更新或删除操作将在从表上进行相应的级联操作。
CREATE TABLE 表1 (
列1 数据类型 PRIMARY KEY
);
CREATE TABLE 表2 (
列2 数据类型,
列3 数据类型,
列4 数据类型,
FOREIGN KEY (列2) REFERENCES 表1(列1) ON DELETE CASCADE
);
外键的限制
外键的引用列必须是唯一索引(Unique Index)或主键,以确保引用的数据是唯一的。
外键列和引用列的数据类型必须相同。
InnoDB 存储引擎支持外键,而 MyISAM 不支持。
外键的优缺点
1)优点
数据一致性:外键可以确保表与表之间的关联关系,维护数据的一致性。通过外键约束,可以避免插入或更新无效的引用,保持数据的完整性。
数据完整性:外键可以防止误删除关联的数据。如果有关联关系的数据存在,删除主表中的记录时,外键约束可以阻止删除,或者通过级联操作删除相关的从表数据。
关联查询: 外键使得关联查询更加方便。可以通过 JOIN 操作轻松地获取关联表的信息,提高查询的灵活性。
2)缺点
性能开销: 外键可能引入一定的性能开销。特别是在大规模的数据库中,维护外键关系可能会影响插入、更新和删除操作的性能。
复杂性:外键关系可能增加数据库结构的复杂性。在设计数据库时,需要仔细考虑外键的引入,以及相关的级联操作和约束。
不同数据库支持不同:不同的数据库管理系统对外键的支持程度和实现方式可能有所不同。在切换数据库引擎或迁移数据时,可能会遇到兼容性问题。
简单例子
mysql 5.7
创建外键约束
当创建两张表,其中一张是用户表,另一张是用户拓展表,可以使用外键来建立它们之间的关联。
以下是一个具体的例子:
-- 创建用户表
CREATE TABLE users (
id INT PRIMARY KEY,
username VARCHAR(255) NOT NULL
);
-- 创建用户拓展表,并添加外键关联
CREATE TABLE user_extra (
user_id INT PRIMARY KEY,
remark VARCHAR(255),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
元数据查询
可以通过 sql 查询对应的引用信息
SELECT
TABLE_NAME,
COLUMN_NAME,
CONSTRAINT_NAME,
REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME
FROM
information_schema.KEY_COLUMN_USAGE
WHERE
REFERENCED_TABLE_SCHEMA = 'test';
数据如下:
+------------+-------------+-------------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+------------+-------------+-------------------+-----------------------+------------------------+
| user_extra | user_id | user_extra_ibfk_1 | users | id |
+------------+-------------+-------------------+-----------------------+------------------------+
初始化数据
insert into users(id, username) values (1, 'u1');
insert into user_extra(user_id, remark) values (1, 'u1-ex');
如下:
mysql> select * from users;
+----+----------+
| id | username |
+----+----------+
| 1 | u1 |
+----+----------+
1 row in set (0.00 sec)
mysql> select * from user_extra;
+---------+--------+
| user_id | remark |
+---------+--------+
| 1 | u1-ex |
+---------+--------+
1 row in set (0.00 sec)
测试删除级联
我们直接把 user 表删除
delete from users where id = 1;
此时 user_extra 也同步被清空了。
mysql> select * from user_extra;
Empty set (0.00 sec)
小结
外键对于保证数据一致性,还是比较方便的。
但是为什么现在工作中很少见到呢?
不建议使用的情况:
在某些情况下,可能会有人不太建议使用外键,主要基于以下考虑:
- 性能优化: 有些数据库设计师和开发者更倾向于手动管理关联关系,以更好地控制性能。手动维护关联关系可能允许更灵活的优化策略。
- 水平分片: 在水平分片的情况下,外键可能会增加复杂性。某些数据库系统对分片上的外键支持可能有限,因此在这种情况下可能会选择不使用外键。
- 微服务架构: 在微服务架构中,服务之间的解耦是一个关键设计原则。有些团队认为外键引入了过多的服务之间的耦合,因此选择在微服务架构中限制外键的使用。
每一种技术都有适合的场景,我们结合自己的业务来实现。
作者丨叶止水
来源丨网址:cnblogs.com/houbbBlogs/p/18008015
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
活动推荐
2024 XCOPS智能运维管理人年会·广州站将于5月24日举办,深究大模型、AI Agent等新兴技术如何落地于运维领域,赋能企业智能运维水平提升,构建全面运维自治能力!
相关推荐
- Linux高性能服务器设计
-
C10K和C10M计算机领域的很多技术都是需求推动的,上世纪90年代,由于互联网的飞速发展,网络服务器无法支撑快速增长的用户规模。1999年,DanKegel提出了著名的C10问题:一台服务器上同时...
- 独立游戏开发者常犯的十大错误
-
...
- 学C了一头雾水该咋办?
-
学C了一头雾水该怎么办?最简单的方法就是你再学一遍呗。俗话说熟能生巧,铁杵也能磨成针。但是一味的为学而学,这个好像没什么卵用。为什么学了还是一头雾水,重点就在这,找出为什么会这个样子?1、概念理解不深...
- C++基础语法梳理:inline 内联函数!虚函数可以是内联函数吗?
-
上节我们分析了C++基础语法的const,static以及this指针,那么这节内容我们来看一下inline内联函数吧!inline内联函数...
- C语言实战小游戏:井字棋(三子棋)大战!文内含有源码
-
井字棋是黑白棋的一种。井字棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、三子旗等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时...
- C++语言到底是不是C语言的超集之一
-
C与C++两个关系亲密的编程语言,它们本质上是两中语言,只是C++语言设计时要求尽可能的兼容C语言特性,因此C语言中99%以上的功能都可以使用C++完成。本文探讨那些存在于C语言中的特性,但是在C++...
- 在C++中,如何避免出现Bug?
-
C++中的主要问题之一是存在大量行为未定义或对程序员来说意外的构造。我们在使用静态分析器检查各种项目时经常会遇到这些问题。但正如我们所知,最佳做法是在编译阶段尽早检测错误。让我们来看看现代C++中的一...
- ESL-通过事件控制FreeSWITCH
-
通过事件提供的最底层控制机制,允许我们有效地利用工具箱,适时选择使用其中的单个工具。FreeSWITCH是一个核心交换与混合矩阵,它周围有几十个模块提供各种功能特性。我们完全控制了所有的即时信息,这些...
- 物理老师教你学C++语言(中篇)
-
一、条件语句与实验判断...
- C语言入门指南
-
当然!以下是关于C语言入门编程的基础介绍和入门建议,希望能帮你顺利起步:C语言入门指南...
- C++选择结构,让程序自动进行决策
-
什么是选择结构?正常的程序都是从上至下顺序执行,这就是顺序结构...
- C++特性使用建议
-
1.引用参数使用引用替代指针且所有不变的引用参数必须加上const。在C语言中,如果函数需要修改变量的值,参数必须为指针,如...
- C++程序员学习Zig指南(中篇)
-
1.复合数据类型结构体与方法的对比C++类:...
- 研一自学C++啃得动吗?
-
研一自学C++啃得动吗?在开始前我有一些资料,是我根据网友给的问题精心整理了一份「C++的资料从专业入门到高级教程」,点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!!个人...
- C++关键字介绍
-
下表列出了C++中的常用关键字,这些关键字不能作为变量名或其他标识符名称。1、autoC++11的auto用于表示变量的自动类型推断。即在声明变量的时候,根据变量初始值的类型自动为此变量选择匹配的...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
因果推断Matching方式实现代码 因果推断模型
-
git pull命令使用实例 git pull--rebase
-
git pull 和git fetch 命令分别有什么作用?二者有什么区别?
-
面试官:git pull是哪两个指令的组合?
-
git 执行pull错误如何撤销 git pull fail
-
git fetch 和git pull 的异同 git中fetch和pull的区别
-
git pull 之后本地代码被覆盖 解决方案
-
还可以这样玩?Git基本原理及各种骚操作,涨知识了
-
git命令之pull git.pull
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mysql max (33)
- vba instr (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)