携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
前言
上篇我们学习了MySQL学习-自增列。有兴趣的小伙伴可以阅读(# MySQL学习-自增列)。
下面学习MySQL中的FOREIGN KEY约束。
FOREIGN KEY约束
作用
FOREIGN KEY约束用于限定某个表的某个字段的引用完整性。比如员工表的员工所在部门的选择,必须在部门表能找到对应的部门。
关键字
FOREIGN KEY
主表和从表与父表和子表概念
- 主表(父表):被引用的表,被参考的表。
- 从表(子表):引用别人的表,参考别人的表。
举例一
员工表的员工所在部门这个字段参考的值要参考部门表:部门表是主表,员工表是从表。
举例二
学生表,课程表,选课表:选课表的学生和课程要分别参考学生表和课程表,学生表和课程表是主表,选课表是从表。
特点
- 从表的外键列,必须引用/参考主表的主键或唯一约束的列,因为被引用/参考的值必须是唯一的。
- 在创建外键约束时,如果不给外键的约束命名,默认名不是列名,而是自动产生一个外键名,也可以指定外键约束名。
- 创建表时就指定外键约束的话,先创建主表,再创建从表。
- 删表时,先删从表(或先删除外键约束),再删除主表。
- 当主表的记录被从表参照时,主表的记录将不允许删除,如果要删除数据,需要先删除从表中依赖该记录的数据,然后才可以删除主表的数据。
- 在从表中指定外键约束,并且一个表可以创建多个外键约束。
- 从表的外键列与主表被参照的列名字可以不相同,但是数据类型必须一样,逻辑意义一致。如果类型不一致,创建子表时,就会出现错误。
- 当创建外键约束时,系统默认会在所在列上建立对应的普通索引。但是索引名是外键的约束名。(根据外键查询效率更高)。
- 删除外键约束后,必须手动删除对应的索引。
增加外键约束
增加外键约束,可以在创建表时,也可以在创建表后。
创建表时
CREATE TABLE 主表名(
字段名 数据类型 PRIMARY KEY,
字段名 数据类型
);
CREATE TABLE 从表名(
字段名 数据类型 PRIMARY KEY,
字段名 数据类型,
[CONSTRAINT <外键约束名称>]
FOREIGN KEY (从表的字段) REFERENCES 主表名(被参考的字段)
);
举例三
创建主表dept,从表emp。
CREATE TABLE dept(
department_id INT PRIMARY KEY,
department_name VARCHAR(50)
);
CREATE TABLE emp(
employee_id INT PRIMARY KEY,
name VARCHAR(50),
dept_id INT,
FOREIGN KEY (dept_id) REFERENCES dept(department_id)
);
- 创建外键约束,必须先创建主表,创建成功后,才能创建从表,指定外键成功。
- 删除表时,先删除从表emp,再删除主表dept。
创建表后
一般情况下,表与表的关联都是提前设计好的,因此,会在创建表的时候就把外键约束定义好。不过,如果需要修改表的设计时,但没有预先定义外键约束,则用修改表的方式补充定义。
ALTER TABLE emp ADD FOREIGN KEY (从表的字段) REFERENCES 主表名(被参考的字段)
总结:
- 增加外键约束后,主表的修改和删除数据受约束。
- 增加外键约束后,从表的增加和修改数据受约束。
- 在从表上建立外键,要求主表必须存在。
- 删除主表时,要先删除从表,或将从表中外键引用该主表的关系先删除。
约束等级
- Cascade方式:在主表上update/delete时,同步update/delete从表的匹配记录。
- Set NULL方式:在主表上update/delete时,将从表上匹配记录的列设为NULL,但是注意从表的外键列不能为NOT NULL。
- No action方式:如果从表有匹配的记录,则不允许对主表对应候选键进行update/delete操作。
- Restrict方式:同No action,都是立即检查外键约束。
- Set default方式:主表有变更时,从表将外键列设置成一个默认的值,但Innodb不能识别。
如果没有指定等级,就相当于Restrict方式,对于外键约束,最好采用:ON UPDATE CASCADE ON DELETE RESTRICT的方式。
删除外键
1. 先查看约束名和删除外键约束
SELECT * FROM information_schema.table_constraints
WHERE table_name = '表名';
ALTER TABLE 从表名 DROP FOREIGN KEY 外键约束名;
2. 查看索引名和删除索引(注意,只能手动删除)
SHOW INDEX FROM 表名;
ALTER TABLE 从表名 DROP INDEX 索引名;
阿里规范
【强制】 不得使用外键与级联,一切外键概念必须在应用层解决。
外键与级联更新适用于单机低并发,不适用分布式,高并发集群,级联更新是强阻塞,存在数据库更新风暴的风险,外键影响数据库的插入速度。
今天先学习到这里,明天继续。