外键用于定义主表和从表之间的关系 外键约束主定义在从表的列上,主表关联的列必须是主键或唯⼀约束 当定义外键后,要求从表中的外键列数据必须在主表的主键或唯⼀列存在或为null。

drop table if exists class;
# 建表
create table class (
id bigint primary key auto_increment,
name varchar(20) not null
);
# 初始化数据
insert into class (name) values ('java'), ('C'), ('C++'), ('python'), ('go');
select * from class;
语法:
foreign key (id) references class(id)drop table if exists student;
# 重构表
create table student(
id bigint PRIMARY KEY auto_increment,
name varchar(20) not null,
age int DEFAULT 18,
class_id bigint,
foreign key (class_id) references class(id) # 创建外键约束
);Key列的值为MUL表示外键约束的列
desc student;
正常插入数据
# 班级编号在主表中存在
insert into student(name, class_id) values ('张三', 1), ('李四', 2);
# 插⼊成功
select * from student;
插入⼀个班级号为100的学生,由于主表中没有这个班级,插入失败
# 班级编号在主表中不存在,提⽰外键约束限制导致插⼊失败
insert into student(name, class_id) values ('王五', 100);
插入班级Id为NULL的记录,可以成功,表示当前学⽣还没有分配置班级
# 班级为NULL
insert into student(name, class_id) values ('王五', NULL);
select * from student;
删除主表某条记录时,从表中不能有对该记录的引用
# 删除从表中没有引⽤的记录,可以成功
delete from class where name = 'go';
select * from class;
# 删除从表中引⽤的记录,失败
delete from class where name = 'java';
删除主表时要先删除从表
# 从表存在是不能删除主表
drop table class;
# 删除从表
drop table student;
# 再删除主表,成功
drop table class;
#注:
(1)外键约束虽然让我们感觉起来很麻烦,但却是不可缺失的!!!
(2)使用外键约束可以增添校验能力,有效减少错误的发生
可以应用于⼀个或多个列,用于限制列中可接受的数据值,从而确保数据的完整性和准确性。 在8.0.16开始全面支持check约束,之前的版本会忽略check的定义
有以下要求,年龄不能小于16岁,性别只能是男或女(在某些国家,性别的数量高达几十种!!!)
drop table if exists student;
# 加⼊CHECK约束
create table student(
id bigint PRIMARY KEY auto_increment, # 设置⾃增主键
name varchar(20) not null,
age int DEFAULT 18,
gender char(1),
check (age >= 16),
check (gender = '男' or gender = '⼥')
);
# 正常插⼊数据
insert into student(name, age, gender) values ('张三', 17, '男'), ('李四',19,'女');
select * from student;
# 插⼊年龄⼩于16岁的记录,失败
insert into student(name, age, gender) values ('张三', 15, '男');
# 插⼊性别的值不是男或⼥的记录,失败
insert into student(name, age, gender) values ('张三', 17, '1');
c1的值不能为0,c2的值必须大于0,c3的值不小于c2
# 列与列之间也可以⽐较,需要在单独⼀⾏中定义
create table t_check (
c1 int check(c1 <> 0),
c2 int check(c2 > 0),
c3 int,
check(c3 >= c2)
);
# 插⼊正常数据
insert into t_check values (-1, 3, 10);
select * from t_check;
# c1 = 0时,失败
insert into t_check values (0, 5, 6);
# c2 <= 0时,失败
insert into t_check values (2, -10, 10);
# c3 < c2时,失败
insert into t_check values (2, 10, 9);