一、约束的基本概念

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

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

  3、分类

    • 非空约束(not null):限制该字段的数据不能为null
    • 唯一约束(unique):保证该字段的所有数据都是唯一,不重复的
    • 主键约束(primary key):主键是一行数据的唯一标识,要求非空且唯一
    • 默认约束(default):保存数据时,如果未指定该字段的值,则采用默认值
    • 检查约束(check 8.0以后的新约束):保证字段满足某一个条件
    • 外键约束(foreign key):用来让两张变的数据建立连接,保证数据的一致性和完整性

二、约束的案例实践

  需求1:创建一个表id、name、age、address、stu_num五个字段。

  需求2:id字段为主键,且设置为自动递增。

  需求3:name字段长度为10个字符并且不能为空。

  需求4:age字段要大于0并且小于150.

  需求5:address字段如果不设,默认为广州。

  需求6:stu_num唯一且不能为空。

mysql> create table stu_table(
-> id int primary key auto_increment comment "id主键",
-> name varchar(10) not null comment "姓名",
-> age int check(age>0 && age<150) comment "年龄",
-> address varchar(10) default "广州" comment "地址",
-> stu_num int not null unique comment "学号"
-> ) comment "学生表";
Query OK, 0 rows affected, 1 warning (0.03 sec)

  stu_table的表结构如下

mysql> desc stu_table;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(10) | NO | | NULL | |
| age | int | YES | | NULL | |
| address | varchar(10) | YES | | 广州 | |
| stu_num | int | NO | UNI | NULL | |
+---------+-------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)

  说明:

    • Type 是字段的类型
    • Null 是是否允许为空
    • key 是标记主键,外键和唯一的
    • Default 是该字段的默认值
    • Extra 是一些额外信息的展示

  验证1:添加一组正常数据

mysql> insert into stu_table (name, age, address, stu_num) values ("张三", 18, "深圳",10001);
Query OK, 1 row affected (0.00 sec) mysql> select * from stu_table;
+----+--------+------+---------+---------+
| id | name | age | address | stu_num |
+----+--------+------+---------+---------+
| 1 | 张三 | 18 | 深圳 | 10001 |
+----+--------+------+---------+---------+
1 row in set (0.00 sec)

  说明1:各个字段都复合各个字段的要求,添加正常没有问题

  验证2:添加一个name 超过10位的异常数据

mysql> insert into stu_table (name, age, address, stu_num) values ("ABCDEFGHIJK", 18, "深圳",10002);
ERROR 1406 (22001): Data too long for column 'name' at row 1

  说明2:直接报错,提示 name  data too long 太长了

  验证3:验证age 大于150的异常情况

mysql> insert into stu_table (name, age, address, stu_num) values ("李四", 152, "深圳",10003);
ERROR 3819 (HY000): Check constraint 'stu_table_chk_1' is violated.

  说明3:这里提示了一个验证错误

  验证4:验证address不填写,默认值的设置

mysql> insert into stu_table (name, age, stu_num) values ("李四", 19,10002);
Query OK, 1 row affected (0.01 sec) mysql> select * from stu_table;
+----+--------+------+---------+---------+
| id | name | age | address | stu_num |
+----+--------+------+---------+---------+
| 1 | 张三 | 18 | 深圳 | 10001 |
| 2 | 李四 | 19 | 广州 | 10002 |
+----+--------+------+---------+---------+
2 rows in set (0.00 sec)

  说明4:在上面的insert 语句中只设置了name,age,stu_num三个字段,所以adderss就自动设置了默认值广州

  验证5:验证stu_num字段的唯一性

mysql> insert into stu_table (name, age, address, stu_num) values ("王五", 21, "上海",10002);
ERROR 1062 (23000): Duplicate entry '10002' for key 'stu_table.stu_num'

  说明5:提示10002已经重复了

三、外键约束介绍

  1、什么是外键

    • 首先外键是表中一个字段
    • 外键是两张表之间的纽带
    • 设置外键的表称之为子表,外键对应的表称之为父表

  2、外键的介绍

    

    说明1:《学生表》和《辅导员》表示两张相互独立的表。

    说明2:在《学生表》中的辅导员编号,和《辅导员表》中的辅导员编号是一一对应的

    说明3:这种情况下就可以通过辅导员编号这个字段将《学生表》和《辅导员表》联系起来了

    说明4:这是辅导员编号字段,就符合设置为外键的条件

    说明5:如果将《学生表》中的辅导员编号字段设置为外键,则《学生表》为子表,《辅导员表》为父表

    说明6:外键在父表中是唯一,不可重复的。

  3、多外键展示

    

    说明1:通过上图发现《学生表》中的班级id和《班级表》中的班级id也存在一一对应的关系

    说明2:班级id也符合设置外键的标准。

    说明3:例如:辅导员编号,班级id都符合外键的设置标准,所以一个表中可以有多个外键,但是每个外键对应不同的表

  4、不符合外键的展示

    

    说明1:在《学生表》班级评级字段和《班级考核与平级对照表》中的班级平级字段也存在着关系。

    说明2:但是这个班级评级字段就不存在外键的特征,因为班级评级在《班级考核与评级对照表》中不是惟一的。

    说明3:在子表中的四星,对应父表中有三种情况这样就会出现子表中的四星到底对应父表的哪一个四星的情况。

四、外键约束展示

  1、原始数据:student表结构及其数据

mysql> select * from student;
+----+----------+------------+-------+
| id | stu_name | teacher_id | score |
+----+----------+------------+-------+
| 1 | stu1 | 1 | 98 |
| 2 | stu2 | 1 | 88 |
| 3 | stu3 | 2 | 79 |
| 4 | stu4 | 2 | 97 |
| 5 | stu5 | 3 | 93 |
| 6 | stu6 | 3 | 86 |
+----+----------+------------+-------+
6 rows in set (0.00 sec)

  2、原始数据:teacher表结构及其数据

mysql> select * from teacher;
+------------+--------------+
| id | teacher_name |
+------------+--------------+
| 1 | 张三 |
| 2 | 李四 |
| 3 | 王五 |
+------------+--------------+
3 rows in set (0.00 sec)

  3、添加外键的语法

alter table 表名 add constraint 外键名称 foreign key (外键字段名) references 父表 (父表字段)on update 更新行为 on delete 删除行为

    说明1:alter table 是DML语法,修改表的意思,在之前的文章中已经介绍过

    说明2:add constraint 是添加约束的意思

    说明3:foreign key 是外键约束的关键字

    说明4:references 后面跟上父表和父表中字段

  4、需求:给student表中的teacher_id设置为teacher表的外键,并且对应id字段的数据

mysql> alter table student add constraint fk_teacher foreign key (teacher_id) references teacher (id);
Query OK, 6 rows affected (0.22 sec)
Records: 6 Duplicates: 0 Warnings: 0

    说明1:外键一旦设置成功,将会保持子表和父表的数据一致性和完整性。

    说明2:这个时候,如果我删除《teacher》表中的id=1的张三老师,就会出错,因为,如果张三在《teacher》表中删除了,则在《student》中的辅导员编号这列数据就找不到对应的值

    说明3:从而这样就破坏了数据的完整性和一致性

mysql> delete from teacher where id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`mysql_test`.`student`, CONSTRAINT `fk_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`id`))

    说明1:这个时候就会提示,不能删除或者修改父表中的数据,因为有外键存在

  5、外键数据的更新和删除行为

    • no action:当在父表中删除/更新对应记录时,首先检查该记录是否有对应的外键,如果有则不允许删除/更新(与restrict一致)
    • restrict:当在父表中删除/更新对应记录时,首先检查该记录是否有对应的外键,如果有则不允许删除/更新(与 no action一致)
    • cascade:当在父表中删除/更新对应记录时,首先检查该记录是否有对应的外键,如果有,则也删除/更新外键在子表中的记录
    • set null:当在父表中删除/更新对应记录时,首先检查该记录是否有对应的外键,如果有则设置子表中该外键的值为null,这就要求该外键记录允许null
    • set default:父表有变更时,子表将外键列设置成一个默认的值(Innodb不支持)

  6、重新创建《student》和《teacher》表并添加外键

mysql> select * from student;
+----+----------+------------+-------+
| id | stu_name | teacher_id | score |
+----+----------+------------+-------+
| 1 | stu1 | 1 | 98 |
| 2 | stu2 | 1 | 88 |
| 3 | stu3 | 2 | 79 |
| 4 | stu4 | 2 | 97 |
| 5 | stu5 | 3 | 93 |
| 6 | stu6 | 3 | 86 |
+----+----------+------------+-------+
6 rows in set (0.00 sec) mysql> select * from teacher;
+----+--------------+
| id | teacher_name |
+----+--------------+
| 1 | 张三 |
| 2 | 李四 |
| 3 | 王五 |
+----+--------------+
3 rows in set (0.00 sec) mysql> alter table student add constraint fk_teacher foreign key (teacher_id) references teacher(id) on update cascade on delete cascade;
Query OK, 6 rows affected (0.05 sec)
Records: 6 Duplicates: 0 Warnings: 0

  7、验证cascade级联行为

    验证1:我修改《teacher》表中id=1的数据改为id=4

mysql> update teacher set id=4 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from teacher;
+----+--------------+
| id | teacher_name |
+----+--------------+
| 2 | 李四 |
| 3 | 王五 |
| 4 | 张三 |
+----+--------------+
3 rows in set (0.01 sec) mysql> select * from student;
+----+----------+------------+-------+
| id | stu_name | teacher_id | score |
+----+----------+------------+-------+
| 1 | stu1 | 4 | 98 |
| 2 | stu2 | 4 | 88 |
| 3 | stu3 | 2 | 79 |
| 4 | stu4 | 2 | 97 |
| 5 | stu5 | 3 | 93 |
| 6 | stu6 | 3 | 86 |
+----+----------+------------+-------+
6 rows in set (0.00 sec)

    说明1:这个时候我们会发现,当我修改了《teacher》表中辅导员编号的id字段是,在《student》表中teacher_id 原本等于1的也都改为了4,这就是cascade的作用

    验证2:cascade的删除行为

mysql> select * from teacher;
+----+--------------+
| id | teacher_name |
+----+--------------+
| 2 | 李四 |
| 3 | 王五 |
+----+--------------+
2 rows in set (0.00 sec) mysql> select * from student;
+----+----------+------------+-------+
| id | stu_name | teacher_id | score |
+----+----------+------------+-------+
| 3 | stu3 | 2 | 79 |
| 4 | stu4 | 2 | 97 |
| 5 | stu5 | 3 | 93 |
| 6 | stu6 | 3 | 86 |
+----+----------+------------+-------+
4 rows in set (0.00 sec)

    说明2:和更新一样,cascade的删除也是级联的。

  8、验证set null的更新和删除行为

    需求1:同样先删除《student》和《teacher》表然后重新建立新的表,重新建立外键约束测试

mysql> select * from teacher;
+----+--------------+
| id | teacher_name |
+----+--------------+
| 1 | 张三 |
| 2 | 李四 |
| 3 | 王五 |
+----+--------------+
3 rows in set (0.00 sec) mysql> select * from student;
+----+----------+------------+-------+
| id | stu_name | teacher_id | score |
+----+----------+------------+-------+
| 1 | stu1 | 1 | 98 |
| 2 | stu2 | 1 | 88 |
| 3 | stu3 | 2 | 79 |
| 4 | stu4 | 2 | 97 |
| 5 | stu5 | 3 | 93 |
| 6 | stu6 | 3 | 86 |
+----+----------+------------+-------+
6 rows in set (0.00 sec) mysql> alter table student add constraint fk_teacher foreign key (teacher_id) references teacher(id) on update set null on delete set null;
Query OK, 6 rows affected (0.04 sec)
Records: 6 Duplicates: 0 Warnings: 0

    验证1:更新《teacher》表中id=1的数据,改为id=4

mysql> update teacher set id=4 where id=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from teacher;
+----+--------------+
| id | teacher_name |
+----+--------------+
| 2 | 李四 |
| 3 | 王五 |
| 4 | 张三 |
+----+--------------+
3 rows in set (0.00 sec) mysql> select * from student;
+----+----------+------------+-------+
| id | stu_name | teacher_id | score |
+----+----------+------------+-------+
| 1 | stu1 | NULL | 98 |
| 2 | stu2 | NULL | 88 |
| 3 | stu3 | 2 | 79 |
| 4 | stu4 | 2 | 97 |
| 5 | stu5 | 3 | 93 |
| 6 | stu6 | 3 | 86 |
+----+----------+------------+-------+
6 rows in set (0.01 sec)

    说明1:对应更新的数据都改为了null

    验证2:删除《teacher》表中id=2的数据

mysql> delete from teacher where id = 2;
Query OK, 1 row affected (0.01 sec) mysql> select * from teacher;
+----+--------------+
| id | teacher_name |
+----+--------------+
| 3 | 王五 |
| 4 | 张三 |
+----+--------------+
2 rows in set (0.00 sec) mysql> select * from student;
+----+----------+------------+-------+
| id | stu_name | teacher_id | score |
+----+----------+------------+-------+
| 1 | stu1 | NULL | 98 |
| 2 | stu2 | NULL | 88 |
| 3 | stu3 | NULL | 79 |
| 4 | stu4 | NULL | 97 |
| 5 | stu5 | 3 | 93 |
| 6 | stu6 | 3 | 86 |
+----+----------+------------+-------+
6 rows in set (0.00 sec)

    说明1:当删除数据的时候,子表中对应的外键数据也会变成了null

五、删除外键约束

  1、删除外键的语法

alter table 表名 drop foreign key 外键名称;
mysql> alter table student drop foreign key fk_teacher;
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0

  2、删除外键后,数据一致性和完整性的验证

mysql> delete from teacher where id=1;
Query OK, 1 row affected (0.01 sec) mysql> select * from teacher;
+----+--------------+
| id | teacher_name |
+----+--------------+
| 2 | 李四 |
| 3 | 王五 |
+----+--------------+
2 rows in set (0.00 sec)

    说明1:这个时候就可以在《teacher》表中删除id=1的张三老师了,但是这样《student》表和《teacher》表的数据的一致性就破坏了

    

Mysql基础7-约束的更多相关文章

  1. 总结: MySQL(基础,字段约束,索引,外键,存储过程,事务)操作语法

    1. 显示数据库列表 show databases; # 查看当前所有数据库 show databases \G   #以行的方式显示 2. 在命令行中,执行sql语句 mysql -e 'show ...

  2. mysql基础之约束

    约束的目的: 1.约束保证数据的完整性和一致性. 2.约束分为表级约束 和 列级 约束.(针对约束字段的数目的多少来确定的) 3.约束类型包括 not null (非空约束) primary key( ...

  3. MySQL基础(三)——约束

    MySQL基础(三)--约束 约束是在表上强制执行的数据校验规则,主要用于维护表中数据的完整性以及当数据之间有以来关系时,保护相关的数据不会被删除. 根据约束对列的限制,可以划分为:单列约束(只约束一 ...

  4. MySQL基础(6) | check约束

    MySQL基础(6) | check约束 前言 在一些情况下,我们需要字段在指定范围的输入, 例如:性别只能输入 '男'或者'女',余额只能大于0等条件, 我们除了在程序上控制以外,我们还能使用 CH ...

  5. Mysql基础代码(不断完善中)

    Mysql基础代码,不断完善中~ /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权限 ...

  6. MYSQL基础操作

    MYSQL基础操作 [TOC] 1.基本定义 1.1.关系型数据库系统 关系型数据库系统是建立在关系模型上的数据库系统 什么是关系模型呢? 1.数据结构可以规定,同类数据结构一致,就是一个二维的表格 ...

  7. mysql 基础篇5(mysql语法---数据)

    6 增删改数据 -- ********一.增删改数据********* --- -- 1.1 增加数据 -- 插入所有字段.一定依次按顺序插入 INSERT INTO student VALUES(1 ...

  8. MySQL基础(二)——DDL语句

    MySQL基础(二)--DDL语句 1.什么是DDL语句,以及DDL语句的作用 DDL语句时操作数据库对象的语句,这些操作包括create.drop.alter(创建.删除.修改)数据库对象. 2.基 ...

  9. MYSQL基础笔记(二)-SQL基本操作

    SQL基本操作 基本操作:CRUD,增删改查 将SQL的基本操作根据操作对象进行分类: 1.库操作 2.表操作 3.数据操作 库操作: 对数据库的增删改查 新增数据库: 基本语法: Create da ...

  10. MYSQL基础笔记(一)

    关系型数据库概念: 1.什么是关系型数据库? 关系型数据库:是一种建立在关系模型(数学模型)上的数据库 关系模型:一种所谓建立在关系上的模型. 关系模型包含三个方面: 1.数据结构:数据存储的问题,二 ...

随机推荐

  1. TiDB在X86和ARM混合平台下的离线部署和升级

    [是否原创]是 [首发渠道]TiDB 社区 背景 在之前我们团队发布了TiDB基于X86和ARM混合部署架构的文章:TiDB 5.0 异步事务特性体验--基于X86和ARM混合部署架构,最近有朋友问到 ...

  2. Network Science:巴拉巴西网络科学阅读笔记2 第一章图论

    第一章:图论 完全图又被称为团. Metcalfe's Law: Metcalfe's law states that the value of a telecommunications networ ...

  3. Lucas定理——定义、证明、实现、运用

    目录 什么是Lucas定理 证明Lucas定理 Lucas定理求解组合数的C++实现 什么是Lucas定理 这是一个有助于分解组合数来求解的定理,适合模数小,数字大的问题. 有质数 \(p\),对于\ ...

  4. MySQL百万数据深度分页优化思路分析

    业务场景 一般在项目开发中会有很多的统计数据需要进行上报分析,一般在分析过后会在后台展示出来给运营和产品进行分页查看,最常见的一种就是根据日期进行筛选.这种统计数据随着时间的推移数据量会慢慢的变大,达 ...

  5. Vue 前端开发团队风格指南(史上最全)

    Vue官网的风格指南按照优先级(依次为必要.强烈推荐.推荐.谨慎使用)分类,本文根据项目实际情况整理了一份适用于团队开发的vue风格指南,供大家参考. 一.命名规范 常用的命名规范: camelCas ...

  6. Linux 给用户赋予操作权限

    赋予local目录读写权限给keesail,别的用户对这个目录没有任何权限. chown -R keesail:keesail ./local chmod 777 文件夹名称,可以把文件夹设置成所有用 ...

  7. autojs系列-js入门1

    开头 确保 Autojs 和 adb 还有模拟器安装调试完成之后,就可以进行js的学习了 调试安装一部分步骤可以参考 https://www.cnblogs.com/c-keke/p/14919615 ...

  8. 2022-02-21:不含连续1的非负整数。 给定一个正整数 n ,返回范围在 [0, n] 都非负整数中,其二进制表示不包含 连续的 1 的个数。 输入: n = 5 输出: 5 解释: 下面是带

    2022-02-21:不含连续1的非负整数. 给定一个正整数 n ,返回范围在 [0, n] 都非负整数中,其二进制表示不包含 连续的 1 的个数. 输入: n = 5 输出: 5 解释: 下面是带有 ...

  9. MMCM and PLL Dynamic Reconfiguration

    Reconfiguration is performed through the DRP. The DRP provides access to the configuration bits that ...

  10. Linux运维5月2号

    了解安装VMware虚拟机  镜像文件 以及镜像文件安装过程中的设置 vmware安装步骤                                                        ...