为了账号安全,请及时绑定邮箱和手机立即绑定

mysql 外键索引入门介绍,为什么工作中很少有人使用?

标签:
MySQL

背景

以前工作学习中,一直被告诫不要使用外键,所以也没有仔细整理过。

这里记录一下笔记。

外键

是什么?

MySQL 的外键(Foreign Key)是一种关系型数据库中用于建立表与表之间关联关系的重要工具。

外键定义了两个表之间的引用关系,它连接了两个表,使它们之间建立起一定的联系。

外键用于维护表与表之间的一致性和完整性,确保数据的准确性和可靠性。

如何定义

在创建表时,可以使用 FOREIGN KEY 关键字来定义外键。外键通常与 REFERENCES 关键字一起使用,用于指定引用的表和列。

外键通常关联到另一个表的主键列,这样它就能确保引用的数据是一致的。

CREATE TABLE 表名 (1 数据类型,2 数据类型,
    ...
    FOREIGN KEY (外键列) REFERENCES 关联表名(关联列)
);

级联操作

外键还可以定义级联操作,包括 CASCADESET NULLSET DEFAULTNO ACTION

这些操作定义了在主表中进行更新或删除操作时,对应的外键列在从表中的行的处理方式。

例如,CASCADE 表示主表的更新或删除操作将在从表上进行相应的级联操作。

CREATE TABLE1 (1 数据类型 PRIMARY KEY
);
CREATE TABLE2 (2 数据类型,3 数据类型,4 数据类型,
    FOREIGN KEY (2) REFERENCES1(1) ON DELETE CASCADE
);

外键的限制

  • 外键的引用列必须是唯一索引(Unique Index)或主键,以确保引用的数据是唯一的。

  • 外键列和引用列的数据类型必须相同。

  • InnoDB 存储引擎支持外键,而 MyISAM 不支持。

外键的优缺点:

优点:

  1. 数据一致性: 外键可以确保表与表之间的关联关系,维护数据的一致性。通过外键约束,可以避免插入或更新无效的引用,保持数据的完整性。

  2. 数据完整性: 外键可以防止误删除关联的数据。如果有关联关系的数据存在,删除主表中的记录时,外键约束可以阻止删除,或者通过级联操作删除相关的从表数据。

  3. 关联查询: 外键使得关联查询更加方便。可以通过 JOIN 操作轻松地获取关联表的信息,提高查询的灵活性。

缺点:

  1. 性能开销: 外键可能引入一定的性能开销。特别是在大规模的数据库中,维护外键关系可能会影响插入、更新和删除操作的性能。

  2. 复杂性: 外键关系可能增加数据库结构的复杂性。在设计数据库时,需要仔细考虑外键的引入,以及相关的级联操作和约束。

  3. 不同数据库支持不同: 不同的数据库管理系统对外键的支持程度和实现方式可能有所不同。在切换数据库引擎或迁移数据时,可能会遇到兼容性问题。

简单例子

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)

小结

外键对于保证数据一致性,还是比较方便的。

但是为什么现在工作中很少见到呢?

不建议使用的情况:

在某些情况下,可能会有人不太建议使用外键,主要基于以下考虑:

  1. 性能优化: 有些数据库设计师和开发者更倾向于手动管理关联关系,以更好地控制性能。手动维护关联关系可能允许更灵活的优化策略。

  2. 水平分片: 在水平分片的情况下,外键可能会增加复杂性。某些数据库系统对分片上的外键支持可能有限,因此在这种情况下可能会选择不使用外键。

  3. 微服务架构: 在微服务架构中,服务之间的解耦是一个关键设计原则。有些团队认为外键引入了过多的服务之间的耦合,因此选择在微服务架构中限制外键的使用。

每一种技术都有适合的场景,我们结合自己的业务来实现。

拓展阅读

本文由博客一文多发平台 OpenWrite 发布!

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消