原在我的 Github 上,欢迎订阅。

其他文章:

前言

外键约束是mysql提供的表与表之间的关联,使用它可以保证数据的一致性和完整性。

但是我问过同事,他们现在开发中不会使用外键约束,主要原因是数据量大或请求很频繁时会导致一些性能问题,实际开发中是通过业务代码来代替外键约束的功能。

但这不代表不需要学它,如果你的项目数据量不是很大,用外键约束还是非常方便的。

什么是外键

通过之前学习和练习,外键其实已经出现过,比如在student表中:

学生表中包含一个class_id,它指向class(班级表)的id,于是我们可以通过class_id来查找这个学生的班级信息。

此时,对于student表来说class_id就是它的外键,外键字面意思就是指向外部的某个键,这里就是指向外部class表的id

外键约束

多了“约束”两个字。 有约束代表着不能对含有外键关联的表随意删除和修改了,举个例子:

学生表 和 班级表 相互关联并有约束条件,如果有一天,你要删除某个班级,那班级里的学生怎么办呢?默认数据库会不让你删,因为班里还有学生存在。

OK,我们实际操作一把,现在把学生表和班级表加个外键约束:

ALTER TABLE student ADD CONSTRAINT student_class FOREIGN KEY (class_id) REFERENCES class(id);

解析一下上面的语句:

  • ALTER TABLE student :对 student 表进行操作
  • ADD CONSTRAINT student_class:添加约束,名称为 student_class
  • FOREIGN KEY (class_id):指定外键是 class_id
  • REFERENCES class(id):关联(参考) class 表的 id

看下结果:

为了好理解再看下 ER 图:

ON DELETE 和 ON UPDATE

ON DELETE 和 ON UPDATE 表示删除时 和 更新时 要处理的方式。

上面图里有删除时更新时,这是数据删除和更新时的处理方式:

  • NO ACTION 或 RESTRICT:对父表删除或更新时,必须把子表处理完才能删除或更新主表数据
  • CASCADE:对父表删除或更新时,子表同时删除或更新
  • SET NULL:对父表删除或更新时,子表设置为NULL

默认为 RESTRICT 。

NO ACTION 或 RESTRICT

来看下设置为 NO ACTION 或 RESTRICT 时,我们删除和更新数据试试:

id=1 的班级表中有对应的学生,我们来删除这个班级:

DELETE FROM class WHERE id=1;

更新也是一样:

UPDATE class SET id=10    WHERE id=1;

CASCADE

CASCADE: 对父表删除或更新时,子表同时删除或更新

我们来试一把。
先修改外键约束:

ALTER TABLE student DROP FOREIGN KEY student_class;

ALTER TABLE student ADD 
CONSTRAINT student_class 
FOREIGN KEY (class_id) 
REFERENCES class(id)
ON DELETE CASCADE
ON UPDATE CASCADE;


可以看到已经改为CASCADE了。
需要注意的是,要先删除外键约束 然后再重新生成。

现在我们来删除id=2的班级:

DELETE FROM class WHERE id=2;

然后来看看班级和学生:

班级表中 id=2 的数据已经没有了

再看看学生表:

class_id=2 的学生也一起删了

现在修改一下试试,我们把id=1 的班级修改为 id=10:

UPDATE class SET id=10 WHERE id=1;

修改成功:

再看看原本class_id=1的学生怎么样了:

class_id 也变成 10

SET NULL

SET NULL:对父表删除或更新时,子表设置为NULL

先把外键约束改成 SET NULL 的处理方式:

ALTER TABLE student DROP FOREIGN KEY student_class;

ALTER TABLE student 
ADD CONSTRAINT student_class 
FOREIGN KEY (class_id) 
REFERENCES class(id) 
ON DELETE SET NULL
ON UPDATE SET NULL;

为了演示方便,在student表中添加一条数据:

现在我们删除 id=3 的班级:

id=3的班级已经被删除,再看看 class_id=3 的学生怎么样了:

从图中看到,由于class_id=3这个班级被删除,这个班里的学生没有了班级,所以class_idNULL了。

我们再看下更新:

UPDATE class SET id=100 WHERE id=10;

上面语句是把id=10的班级改为id=100

班级修改成功了,再看看这个班级下的学生:

原本 class_id=10 的学生现在也没有了班级,class_id 也置为 NULL 了。

总结

本篇学习了什么是外键约束,以及外键约束的几个处理方式:

  • NO ACTION 或 RESTRICT:对父表删除或更新时,必须把子表处理完才能删除或更新主表数据
  • CASCADE:对父表删除或更新时,子表同时删除或更新
  • SET NULL:对父表删除或更新时,子表设置为NULL

默认为 RESTRICT 。


alwaysVe
1.9k 声望162 粉丝

前进