第06章03节-约束constraint

约束constraint



创建表时,可以给表的字段添加约束,可以保证数据的完整性、有效性。比如我们上网注册用户时常见的:用户名不能为空。对不起,用户名已存在。等提示信息。
约束通常包括:

  • 非空约束:not null

  • 检查约束:check

  • 唯一性约束:unique

  • 主键约束:primary key

  • 外键约束:foreign key

1. 非空约束


  • not null

语法格式:

1
2
3
4
5
create table t_stu(
no int,
name varchar(255) not null,
age int
);

name字段不能为空。插入数据时如果没有给name指定值,则报错。

2. 检查约束


  • check

语法格式:

1
2
3
4
5
6
create table t_stu(
no int,
name varchar(255),
age int,
check(age > 18)
);

3. 唯一性约束


  • unique

语法格式:

1
2
3
4
5
create table t_stu(
no int,
name varchar(255),
email varchar(255) unique
);

email字段设置为唯一性,唯一性的字段值是可以为NULL的。但不能重复。以上在字段后面添加的约束,叫做列级约束
当然,添加约束还有另一种方式,表级约束

1
2
3
4
5
6
create table t_stu(
no int,
name varchar(255),
email varchar(255),
unique(email)
);

使用表级约束可以为多个字段添加联合唯一

1
2
3
4
5
6
create table t_stu(
no int,
name varchar(255),
email varchar(255),
unique(name,email)
);

意思是name,email中可以有一个重复,但是都重复了就报错。

创建约束时也可以给约束起名字,将来可以通过约束的名字删除约束

1
2
3
4
5
6
create table t_stu(
no int,
name varchar(255),
email varchar(255),
constraint t_stu_name_email_unique unique(name,email)
);

所有的约束都存储在一个系统表当中:table_constraints,这个系统表在这个数据库当中:information_schema。

4. 主键约束


  1. 主键:primary key,简称PK。
  2. 主键约束的字段不能为NULL,并且不能重复
  3. 任何一张表都应该有主键,没有主键的表可以视为无效表。
  4. 主键值是这行记录的身份证号,是唯一标识。在数据库表中即使两条数据一模一样,但由于主键值不同,我们也会认为是两条完全的不同的数据。
  5. 主键分类:
    1. 根据字段数量分类:
      1. 单一主键(1个字段作为主键) [✓]
      2. 复合主键(2个或2个以上的字段作为主键)
    2. 根据业务分类:
      1. 自然主键(主键和任何业务都无关,只是一个单纯的自然数据) [✓]
      2. 业务主键(主键和业务挂钩,例如:银行卡账号作为主键)
  • 单一主键(建议使用这种方式)
1
2
3
4
5
create table t_student(
id bigint primary key,
sno varchar(255) unique,
sname varchar(255) not null
)
  • 复合主键(很少用,了解)
1
2
3
4
5
6
create table t_user(
no int,
name varchar(255),
age int,
primary key(no,name)
);
  • 主键自增:既然主键值是一个自然的数字,mysql为主键值提供了一种自增机制,不需要程序员维护,mysql自动维护该字段
1
2
3
4
create table t_vip(
no int primary key auto_increment,
name varchar(255)
);

5. 外键约束


有这样一个需求:要求设计表,能够存储学生以及学校信息。

  1. 第一种方案:一张表

image.png
这种方式会导致数据冗余,浪费空间。

  1. 第二种方案:两张表:一张存储学校,一张存储学生。

image.png

image.png

如果采用以上两张表存储数据,对于学生表来说,sno这个字段的值是不能随便填的,这个sno是学校编号,必须要求这个字段中的值来自学校表的sno。为了达到要求,此时就必须要给t_student表的sno字段添加外键约束了。

  1. 外键约束:foreign key,简称FK
  2. 添加了外键约束的字段中的数据必须来自其他字段,不能随便填。
  3. 假设给a字段添加了外键约束,要求a字段中的数据必须来自b字段,b字段不一定是主键,但至少要有唯一性
  4. 外键约束可以给单个字段添加,叫做单一外键。也可以给多个字段联合添加,叫做复合外键。复合外键很少用。
  5. a表如果引用b表中的数据,可以把b表叫做父表,把a表叫做子表。
    1. 创建表时,先创建父表,再创建子表。
    2. 插入数据时,先插入父表,在插入子表。
    3. 删除数据时,先删除子表,再删除父表。
    4. 删除表时,先删除子表,再删除父表。
  • 如何添加外键:

[!tip]

constraint 外键名称 foreign key(添加外键的字段) references 父表(主键字段)

1
2
3
4
5
6
7
8
9
10
11
12
create table t_school( 
sno int primary key,
sname varchar(255)
);

create table t_student(
no int primary key,
name varchar(255),
age int,
sno int,
constraint t_school_sno_fk foreign key(sno) references t_school(sno)
);
  • 级联删除

    on delete cascade

​ 创建子表时,外键可以添加:on delete cascade,这样在删除父表数据时,子表会级联删除。谨慎使用。

1
2
3
4
5
6
7
create table t_student( 
no int primary key,
name varchar(255),
age int,
sno int,
constraint t_school_sno_fk foreign key(sno) references t_school(sno) on delete cascade
);
1
2
3
4
###删除约束
alert table t_student drop foreign key t_student_sno_fk;
###添加约束
alert table t_student add constraint t_student_sno_fk foreign key(sno) references t_school(sno) on delete cascade;
  • 级联更新

    on update cascade

1
2
3
4
5
6
7
create table t_student( 
no int primary key,
name varchar(255),
age int,
sno int,
constraint t_school_sno_fk foreign key(sno) references t_school(sno) on update cascade
);
  • 级联置空

    on delete set null

1
2
3
4
5
6
7
create table t_student( 
no int primary key,
name varchar(255),
age int,
sno int,
constraint t_school_sno_fk foreign key(sno) references t_school(sno) on delete set null
);