上文我们对数据表的数据进行了相关的CURD操作,但是有时候,我们希望,在存入数据的时候,数据表会自己进行一定的审核,即约束,今天此文将数据表的约束进行介绍!
1. 什么是数据库约束
数据库约束是对数据库表中的数据所施加的规则或条件,用于确保数据的准确性和可靠性。这些约束可以是基于数据类型、值范围、唯一性、非空等原则,以确保数据的正确性和相容性。
2. 约束类型
类型 | 说明 |
---|---|
NOT NULL 非空约束 | 指定非空约束的列不能存储NULL值 |
DEFALUT 默认约束 | 当没有给列赋值时的默认值 |
UNIQUE 唯一约束 | 指定唯一约束的列每行数据必须有唯一的值 |
PRIMARY KEY 主键约束 | NOT NULL 和 UNIQUE 的结合,可以指定一个列或多个列,有助于防止数据重复和提高数据的查询性能 |
FOREIGN KEY 外键约束 | 外键约束是一种关系约束,用于定义两个表之间的关联关系,可以确保数据的完整性和一致性 |
CHECK 约束 | 用于限制列或数据在数据库表中的值,确保数据的准确性和可靠性 |
3. NOT NULL 非空约束
当定义表时某列不允许为NULL时,可以为列添加非空约束
- 比如创建一个学生家庭表,家庭成员名为 NULL 时,这条记录是不完整的
sql
create table family (id bigint,name varchar(20));
- 我们发现家庭成员的名字为NULL ,没有意义
- 此时我们就需要约束name的列不能为NULL,首先删掉原来创建的表,重新创建,在此次创建时,加上相关操作
我们在要约束的列后面加上NOT NULL 即可
- 由于我们为name列进行了非空约束,插入如下NULL 值时就会报错,但插入name的正确值就能通过
- 查看表结构,NULL 列为NO 表示值不允许为NULL ,YES 表示值可以为NULL
4. DEFALUT 默认约束
- 首先我们重新创建一个表,新增年龄列
sql
create table family (id bigint,name varchar(20) NOT NULL, age int);
- 插入一条数据,没有设置默认约束时,不指定年龄的值时列为NULL
- 我们希望插入进来的数据,没有给定年龄时,会默认有年龄,那么我们重构家庭表,为年龄加入默认约束
在要加约束的列名后直接加default 默认值即可
sql
create table family (id bigint,name varchar(20) NOT NULL, age int default 18);
- 我们发现在插入一条记录时,不指定年龄的值时列使用了默认值18 并且表结构中age 列的default列默认为18
- 那么我们如果插入年龄列为NULL 值时,是否还会使用默认值18 呢? 我们来一探究竟 我们发现当我们明确指定插入记录为NULL时,不会使用默认值
5. UNIQUE 唯一约束
- 指定了唯一约束的列,该列的值所在记录中不能重复,比如一个人的身份证号,学生学号等 重构家庭表,新增身份证列
sql
create table family (id bigint,name varchar(20) NOT NULL,age int default 18, number varchar(18));
- 我们发现不设置唯一约束时,身份证号码可以重复
- 重构家庭表,为身份证号列设置唯一约束,在约束的列名后加上UNIQUE 即可
sql
create table family (id bigint,name varchar(20) NOT NULL,age int default 18, number varchar(18) UNIQUE);
- 我们发现为身份证号列添加唯一约束后,相同的则不能插入进去,唯一约束生效
- 查看表结构,Key 列显示UNI 表示唯一约束
6. PRIMARY KEY 主键约束
主键约束唯一标识数据库表中的每条记录。
主键必须包含唯一的值,且不能包含NULL 值。
每个表只能有一个主键,可以由单个和多个列组成。
通常为每张表都指定一个主键,主键列建议使用BIGINT 类型。
- 重构家庭表,为id列添加非空和唯一约束
- 查看表结构,添加了非空和唯一约束之后Key列显示PRI表示主键,
从此发现我们可以知道PRIMARY KEY=NOT NULL +UNIQUE
- 当id列的重复时会发生主键冲突
- 通常把主键列设置为自动增长,让数据库维护主键值 ,
PRIMARY KEY auto_increment
- 插入数据时不设置主键列的值
- 此时我们插入数据时,插入错误了一条,那么我们的自增主键id会走到什么位置呢?? 2还是3?? 我们来查看一下
我们发现id是从3开始,这是为何??
因为在数据库中插入数据正确或者错误,自增主键都会往后走一步,不会回退,这样可以提高查询效率
- 查看表结构,Extra 列显示auto_increment表示自增
- 主键值是自增的 那么是否可以不连续呢?? 此时我们插入主键为100的数据,发现插入成功,
所以主键值可以不连续
- 那么我们在插入100主键值之后,自增主键将会从哪里开始自增呢??
我们发现下一次自增从主键的最大值开始
- 主键或唯一键冲突时的更新操作
- 插入
如果插入时有冲突则更新当前列的值,两行受影响,表示删除了原来的记录,又新写入了一条新的记录
其与update family set name ='钱六',number='3601111111111117' where id=100;
等效
- 更新
两行受影响,表示删除了原来的记录,又新写入了一条新的记录
我们发现最后id=100 行的记录被更改了
- 表中不能有多个主键
7. FOREIGN KEY 外键约束
外键用于定义主表和从表之间的关系
外键约束主定义在从表的列上,主表关联的列必须是主键或唯一约束
当定义外键后,要求从表中的外键列数据必须在主表的主键或唯一列存在或为NULL
8. CHECK 约束
可以应用于一个或多个列,用于限制列中可接受的数据值,从而确保数据的完整性和准确性
在8.0.16开始全⾯⽀持CHECK约束,之前的版本会忽略CHECK的定义
但是注意,一般在应用程序级别校验
sql
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 = '⼥')
);
- 列与列之间也可以⽐较,需要在单独⼀⾏中定义
sql
create table t_check (
c1 int check(c1 <> 0),
c2 int check(c2 > 0),
c3 int,
check(c3 >= c2)
);