MySQL表约束与表关系
表约束
让表的字段内容更加规范。
- not null 非空约束
- default value 默认约束
- unique key 唯一约束
- primary key 主键约束(等同于唯一+非空约束)
- auto_increment 自增长约束
非空约束 not null
通常每个字段都会加非空约束。
sql
-- not null 非空约束
create table student(
id int not null, # id字段有非空约束
stu_name varchar(10) not null # stu_name字段有非空约束
);
-- id值和stu_name值都不允许为空值
insert into student values(1, '张三'); #正确
insert into student(id) values(2); #报错
默认约束 default
sql
-- default value 默认约束
create table t1(
id int,
name varchar(10) not null,
age int default 0 # age字段有默认约束
);
-- age值未给定, 则用默认值填充
insert into t1(id, name) values(1, '张三');
-- age值给定, 则会覆盖掉默认值
insert into t1 values(2, '李四', 18);
select * from t1;

图1. 默认约束
唯一约束 unique key
sql
-- unique key 唯一约束
create table t2(
id int unique key, # id字段有唯一约束
name varchar(10),
age int
);
insert into t2 values(1, '张三', 18);
-- id值不能重复
insert into t2 values(1, '李四', 20); # 报错
-- 允许字段值为Null, 因为Null不等于任何值
insert into t2(name, age) values('王五', 25), ('赵六', 27);
select * from t2;

图2.唯一约束
唯一约束 + 非空约束
sql
create table t3(
id int unique key not null, # id字段有唯一约束+非空约束
name varchar(10),
age int
);
insert into t3 values(1, '张三', 18);
select * from t3;
-- id值不能重复且不能为空
insert into t3 values(1, '张三', 18); # 报错,id值重复
insert into t3(name, age) values('张三', 18); # 报错,id值
主键约束 primary key
主键约束:唯一约束 + 非空约束。
通常一张表只会有一个主键约束。主键约束通常会给到关键字段(ID)。
sql
-- primary key 主键约束
-- 主键约束的第一种写法
create table t4(
id int primary key, # id字段有主键约束
name varchar(10),
age int
);
insert into t4 values(1, '张三', 18);
select * from t4;
-- id值不能重复且不能为空
insert into t4 values(1, '张三', 18); # 报错,id值重复
insert into t4(name, age) values('张三', 18); # 报错,id值为空
-- 主键约束的第二种写法
create table t5(
id int,
name varchar(10),
age int,
primary key(id) # id字段有主键约束
);
自增长约束 auto_increment
用于整数类型的字段,每次添加新数据的时候,都会在上一条记录上加1。
sql
-- auto_increment 自增长约束
-- 默认自增长从1开始
create table t6(
id int primary key auto_increment, # id字段有主键约束+自增长约束
name varchar(10)
);
insert into t6(name) values('张三'),('李四'),('王五');
select * from t6;
create table t7(
id int primary key auto_increment, # id字段有主键约束+自增长约束
name varchar(10)
)auto_increment=2025001; # 指定自增长的起始值
insert into t7(name) values('张三'),('李四'),('王五');
select * from t7;

图3-1.自增长约束,默认从1开始

图3-2.自增长约束,指定自增长的起始值
表关系
通常通过外键约束(foreign key)来让两张表建立模型关系,确保字段值的一致性和完整性。
- 一对一
- 一对多
- 多对多
一对一
主键对主键,学生表中每条数据都能在学生信息表中找到一条与之对应的数据。
具有主键的表称为父表,具有外键的键称为子表。
sql
-- foreign key 外键约束
-- 创建学生表,学生表为父表
create table student(
id int primary key, # id字段有主键约束
stu_name varchar(20) not null
);
-- 给学生表添加数据
insert into student values
(1, '张三'),
(2, '李四');
-- 创建学生信息表,学生信息表为子表
create table stu_detail(
stu_id int primary key,
stu_age int not null,
sex enum('男', '女'),
addr varchar(50) not null,
foreign key(stu_id) references student(id) # 学生信息表的stu_id字段有外键约束,链接到学生表的id字段
);
-- 给学生信息表添加数据
insert into stu_detail values
(1, 18, '男', '长沙'),
(2, 20, '女', '湖北');
-- 报错,不能给子表添加或更新有外键约束的字段数据
-- id值为1、2是父表中已有的,而id值为3是父表中没有的,不能添加
insert into stu_detail values
(3, 18, '男', '北京');
select * from student;
select * from stu_detail;

图4-1.学生表

图4-2.学生信息表
一对多
一位老师可以有多名学生。
sql
-- 创建教师表
create table teacher(
id int primary key,
t_name varchar(10) not null
);
-- 给教师表添加数据
insert into teacher values
(1, 'Lucy'),
(2, 'Amy');
-- 创建学生表
create table student(
id int primary key,
stu_name varchar(10) not null,
t_id int not null,
foreign key(t_id) references teacher(id)
);
-- 给学生表添加数据
insert into student values
(101, '张三', 1),
(102, '李四', 1),
(103, '王五', 2),
(104, '赵六', 2);
select * from teacher;
select * from student;

图5-1.教师表

图5-2.学生表
多对多
多对多关系通过"中间表"来实现。
sql
-- 创建学生表
create table student(
id int primary key,
stu_name varchar(10) not null
);
-- 给学生表添加数据
insert into student values
(1, '张三'),
(2, '李四');
-- 创建课程表
create table course(
id int primary key,
c_name varchar(10) not null
);
-- 给课程表添加数据
insert into course values
(101, 'Python'),
(102, 'Java');
-- 创建选课表,即中间表
create table choose(
stu_id int,
c_id int,
primary key(stu_id, c_id), # 联合主键
foreign key(stu_id) references student(id),
foreign key(c_id) references course(id)
);
-- 给选课表添加数据
insert into choose values
(1, 101),
(1, 102),
(2, 101),
(2, 102);
select * from student;
select * from course;
select * from choose;

图6-1.学生表

图6-2.课程表

图6-3.选课表