> 文章列表 > 【MySQL | 基础篇】03、MySQL 约束

【MySQL | 基础篇】03、MySQL 约束

【MySQL | 基础篇】03、MySQL 约束

目录

一、概述

二、约束演示

三、外键约束

3.1 介绍

3.2 语法

3.3 删除/更新行为


 

一、概述

概念: 约束是作用于表中字段上的规则,用于限制存储在表中的数据

目的:保证数据库中数据的正确、有效性和完整性。

分类:

注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。 

二、约束演示

        上面我们介绍了数据库中常见的约束,以及约束涉及到的关键字,那这些约束我们到底如何在创建表、 修改表的时候来指定呢,接下来我们就通过一个案例,来演示一下。

案例需求: 根据需求,完成表结构的创建。需求如下: 

对应的建表语句为:

create table user(id int primary key auto_increment comment '主键',name varchar(10) not null unique comment '姓名',age int check ( age > 0 && age <= 120 ) comment '年龄',status char(1) default '1' comment '状态',gender char(1) comment '性别'
) comment '用户表';

        在为字段添加约束时,我们只需要在字段之后加上约束的关键字即可,需要关注其语法。我们执行上面的 SQL 把表结构创建完成,然后接下来,就可以通过一组数据进行测试,从而验证一下,约束是否可以生效。 

# 执行成功
insert into user(name,age,status,gender) values ('Tom1',19,'1','男'),('Tom2',25,'0','男');
insert into user(name,age,status,gender) values ('Tom3',19,'1','男');# 执行报错:1048 - Column 'name' cannot be null,name 不能为空
insert into user(name,age,status,gender) values (null,19,'1','男');# 执行报错:1062 - Duplicate entry 'Tom3' for key 'user.name',已存在相同的 name
insert into user(name,age,status,gender) values ('Tom3',19,'1','男');# 执行成功,但是 id 变为 5,因为前面执行 tom3 的时候已经申请了一个 id 4,但是 tom3 已存在
insert into user(name,age,status,gender) values ('Tom4',80,'1','男');# 执行报错:3819 - Check constraint 'user_chk_1' is violated,age 违法 check 约束了
insert into user(name,age,status,gender) values ('Tom5',-1,'1','男');
insert into user(name,age,status,gender) values ('Tom5',121,'1','男');# 执行成功,status 默认为 1
insert into user(name,age,gender) values ('Tom5',120,'男');

执行上面语句后的最终结果:

  

三、外键约束

3.1 介绍

外键:用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。

我们来看一个例子:

        左侧的 emp 表是员工表,里面存储员工的基本信息,包含员工的 ID、姓名、年龄、职位、薪资、入职日 期、上级主管 ID、部门 ID,在员工的信息中存储的是部门的 ID dept_id,而这个部门的 ID 是关联的 部门表 dept 的主键 id,那 emp 表的 dept_id 就是外键,关联的是另一张表的主键。 

注意:目前上述两张表,只是在逻辑上存在这样一层关系;在数据库层面,并未建立外键关联, 所以是无法保证数据的一致性和完整性的。

没有数据库外键关联的情况下,如何能够保证一致性和完整性呢,我们来测试一下。 

准备数据:

create table dept(id   int auto_increment comment 'ID' primary key,name varchar(50) not null comment '部门名称'
)comment '部门表';
INSERT INTO dept (id, name) VALUES (1, '研发部'), (2, '市场部'),(3, '财务部'), (4, '销售部'), (5, '总经办');create table emp(id  int auto_increment comment 'ID' primary key,name varchar(50) not null comment '姓名',age  int comment '年龄',job varchar(20) comment '职位',salary int comment '薪资',entrydate date comment '入职时间',managerid int comment '直属领导ID',dept_id int comment '部门ID'
)comment '员工表';INSERT INTO emp (id, name, age, job,salary, entrydate, managerid, dept_id) VALUES(1, '金庸', 66, '总裁',20000, '2000-01-01', null,5),(2, '张无忌', 20, '项目经理',12500, '2005-12-05', 1,1),(3, '杨逍', 33, '开发', 8400,'2000-11-03', 2,1),(4, '韦一笑', 48, '开发',11000, '2002-02-05', 2,1),(5, '常遇春', 43, '开发',10500, '2004-09-07', 3,1),(6, '小昭', 19, '程序员鼓励师',6600, '2004-10-12', 2,1);

接下来,我们可以做一个测试,删除 id 为 1 的部门信息。 

        结果,我们看到删除成功,而删除成功之后,部门表不存在 id 为 1 的部门,而在 emp 表中还有很多的员工,关联的为 id 为 1 的部门,此时就出现了数据的不完整性。而要想解决这个问题就得通过数据库的外键约束。 

3.2 语法

  • (1)添加外键
CREATE TABLE 表名(字段名 数据类型,...[CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名)
);
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名) ;

案例:

为 emp 表的 dept_id 字段添加外键约束,关联 dept 表的主键 id。

alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);

        添加了外键约束之后,我们再到 dept 表(父表)删除 id 为 1 的记录,然后看一下会发生什么现象。 此时将会报错,不能删除或更新父表记录,因为存在外键约束。

  • (2)删除外键 
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;

案例: 删除 emp 表的外键 fk_emp_dept_id。 

alter table emp drop foreign key fk_emp_dept_id;

3.3 删除/更新行为

        添加了外键之后,再删除父表数据时产生的约束行为,我们就称为删除/更新行为。具体的删除/更新行为有以下几种: 

具体语法为:

ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名 (主表字段名) ON UPDATE CASCADE ON DELETE CASCADE;

演示如下: 

        由于 NO ACTION 是默认行为,我们前面语法演示的时候,已经测试过了,就不再演示了,这里我们再演示其他的两种行为:CASCADE、SET NULL。

  • (1)CASCADE
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id) on update cascade on delete cascade ;

修改父表 id 为 1 的记录,将 id 修改为 6:

        我们发现,原来在子表中 dept_id 值为 1 的记录,现在也变为 6 了,这就是 cascade 级联的效果。 

在一般的业务系统中,不会修改一张表的主键值。

删除父表 id 为 6 的记录:

我们发现,父表的数据删除成功了,但是子表中关联的记录也被级联删除了。 

  • (2)SET NULL

        在进行测试之前,我们先需要删除上面建立两张表。然后再将 emp、dept 表的数据恢复。最后执行下面语句:

alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id) on update set null on delete set null ;

接下来,我们删除父表 id 为 1 的数据,看看会发生什么样的现象。

        我们发现父表的记录是可以正常的删除的,父表的数据删除之后,再打开子表 emp,我们发现子表 emp 的 dept_id 字段,原来 dept_id 为 1 的数据,现在都被置为 NULL 了。 

这就是 SET NULL 这种删除/更新行为的效果。 

上一篇文章:【MySQL | 基础篇】02、MySQL 函数详解_Stars.Sky的博客-CSDN博客

陇南教育网