您现在的位置是:网站首页> 编程资料编程资料

MySQL六种约束的示例详解(全网最全)_Mysql_

2023-05-26 536人已围观

简介 MySQL六种约束的示例详解(全网最全)_Mysql_

一、概述

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

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

分类:

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

二、约束演示

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

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

对应的建表语句为:

CREATE TABLE tb_user ( id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID唯一标识', 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 '性别' ); 

在为字段添加约束时,我们只需要在字段之后加上约束的关键字即可,需要关注其语法。

我们执行上面的SQL把表结构创建完成,然后接下来,就可以通过一组数据进行测试,从而验证一下,约束是否可以生效。

(1)先是新增了三条数据

insert into tb_user(name,age,status,gender) values ('Tom1',19,'1','男'),('Tom2',25,'0','男'); insert into tb_user(name,age,status,gender) values ('Tom3',19,'1','男'); 

新增三条数据,竟然用了21秒,这是什么情况?

本来我还以为是新增这些约束导致新增数据慢的,其实不是,因为我这个是阿里的linux服务器,然后我在linux中通过客户端连接mysql执行新增,也就0.01秒,说明这是navicat连接远程主机耗时的。

就算新增了这些约束,会导致新增数据慢,那也是批量的时候才能明显察觉出来,单条数据基本上看不出来的。

(2)测试name NOT NULL

insert into tb_user(name,age,status,gender) values (null,19,'1','男'); 

(3)测试name UNIQUE(唯一)

上面新增的数据已经有Tom3了,再次新增直接报错。

insert into tb_user(name,age,status,gender) values ('Tom3',19,'1','男'); 

虽然报错了,但是我们这时候再新增一条数据会发现一个现象。

insert into tb_user(name,age,status,gender) values ('Tom4',80,'1','男'); 

明明是自增id,但是却没有4,原因就是UNIQUE(唯一)是在申请完自增id后,准备入库了,然后这时候会先去看看库里面是否有存在相同name的值,如果有则新增失败,虽然新增失败了,但是自增id已经申请过了!

相反我们刚刚测试的null的name的时候他并没有去申请id,因为他在刚开始就已经判断他为空了,还没走到申请id这一步。

判断是否为空 -》 申请自增id -》 判断是否已经有存在的值

总结:当新增的name不为空的时候,但是和之前存在的数据有相同的,这时候新增会失败,但是他会申请主键id。

(4)测试CHECK

我们设置的是age必须大于0小于等于120,否则保存失败!

age int check (age > 0 && age <= 120) COMMENT '年龄' , 
insert into tb_user(name,age,status,gender) values ('Tom5',-1,'1','男'); insert into tb_user(name,age,status,gender) values ('Tom5',121,'1','男'); 

(5)测试 DEFAULT ‘1’ 默认值

STATUS CHAR ( 1 ) DEFAULT '1' COMMENT '状态', 
insert into tb_user(name,age,gender) values ('Tom5',120,'男'); 

(6)上面,我们是通过编写SQL语句的形式来完成约束的指定,那假如我们是Navicat客户端呢?

主键自增

name唯一约束

status默认为1

三、外键约束

1、 什么是外键约束

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

我们来看一个例子:

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

2、 不使用外键有什么影响

通过上面的示例,我们分别来演示 添加外键 和不添加外键的区别,首先来看不添加 外键 对数据有什么影响:

准备数据:

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的部门,此时就出现了数据的不完整性。 而要想解决这个问题就得通过数据库的外键约束。

正常开发当中有时候会通过业务代码来控制数据的不完整性,例如删除部门的时候会先根据部门id去查看一下有没有对应的员工表,如果有则删除失败,没有则删除成功。

3、 添加外键的语法

可以在创建表的时候直接添加外键,也可以对现已存在的表添加外键。

(1)方式一

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

使用示例:

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', CONSTRAINT fk_emp_dept_id FOREIGN KEY (dept_id) REFERENCES dept (id) ) COMMENT '员工表'; 

也可以省略掉CONSTRAINT fk_emp_dept_id 这样mysql就会自动给我们起外键名称。

方式二:对现存在的表添加外键

ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名) ; 

使用示例:

alter table emp add constraint fk_emp_dept_id FOREIGN KEY (dept_id) REFERENCES dept(id); 

方式三:Navicat添加外键

删除外键:

ALTER TABLE 表名 DROP FOREIGN KEY 外键名称; 

使用示例:

alter table emp drop foreign key fk_emp_dept_id; 

4、 删除/更新行为

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

在mysql8.0.27版本当中,RESTRICT是默认的删除更新行为!不同的版本可能也会有所差距!

具体语法为:

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

就是比原先添加外键后面多了这些ON UPDATE CASCADE ON DELETE CASCADE,代表的是更新时采用CASCADE ,删除时也采用CASCADE

5、 演示删除/更新行为

(1)演示RESTRICT

当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。 (与 NO ACTION 一致) 默认行为

首先要添加外键,默认是RESTRICT行为!

alter table emp add constraint fk_emp_dept_id FOREIGN KEY (dept_id) REFERENCES dept(id); 

当我要删除父表当中id为5的记录的时候会报错,原因就是emp表的dept_id存在5。假如要更新id也同样会报错的!

(2)演示CASCADE

当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则

也删除/更新外键在子表中的记录。

删除外键的语法:

ALTER TABLE 表名 DROP FOREIGN KEY 外键约束名; 

删除外键的示例:

ALTER TABLE emp DROP FOREIGN KEY fk_emp_dept_id; 

指定外键的删除更新行为为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

提示: 本文由整理自网络,如有侵权请联系本站删除!
本站声明:
1、本站所有资源均来源于互联网,不保证100%完整、不提供任何技术支持;
2、本站所发布的文章以及附件仅限用于学习和研究目的;不得将用于商业或者非法用途;否则由此产生的法律后果,本站概不负责!

-六神源码网