MySQL基础学习之约束详解

 更新时间:2023年07月20日 09:11:09   作者:Se7eN_HOU  
约束是作用于表中字段上的规则,用于限制储存在表中的数据,这篇文章主要为大家介绍了MySQL中约束的案例以及外键约束的展示与删除,需要的可以参考一下

一、约束的基本概念

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基础学习之约束详解的文章就介绍到这了,更多相关MySQL约束内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mysql内连接,连续两次使用同一张表,自连接方式

    mysql内连接,连续两次使用同一张表,自连接方式

    这篇文章主要介绍了mysql内连接,连续两次使用同一张表,自连接方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • MYSQL的REPLACE和ON DUPLICATE KEY UPDATE语句介绍解决问题实例

    MYSQL的REPLACE和ON DUPLICATE KEY UPDATE语句介绍解决问题实例

    这篇文章主要介绍了MYSQL的REPLACE和ON DUPLICATE KEY UPDATE语句介绍解决问题实例,需要的朋友可以参考下
    2014-04-04
  • MySQL三大日志(binlog、redo log和undo log)图文详解

    MySQL三大日志(binlog、redo log和undo log)图文详解

    日志是MySQL数据库的重要组成部分,记录着数据库运行期间各种状态信息,下面这篇文章主要给大家介绍了关于MySQL三大日志(binlog、redo log和undo log)的相关资料,需要的朋友可以参考下
    2023-01-01
  • MySQL(community版)压缩包安装的超详细教程

    MySQL(community版)压缩包安装的超详细教程

    这篇文章详细介绍了如何在Windows系统上手动安装MySQL 8.0.26的压缩包版本,包括下载、解压、配置环境变量、初始化、启动服务、设置密码等步骤,同时,还提供了一个简单的SQL基础教程,需要的朋友可以参考下
    2025-03-03
  • SQL调优实战之让查询效率飙升10倍的实用技巧

    SQL调优实战之让查询效率飙升10倍的实用技巧

    在数据洪流时代,企业每1毫秒的查询延迟都可能造成百万级营收损失,本文将结合18个真实案例与28段代码示例,揭示从索引设计到执行计划分析的完整优化链路,助你掌握让查询效率提升10倍的核心方法,实现降本增效的技术跃迁
    2026-01-01
  • 解决MySQL 5.7中定位DDL被阻塞的问题

    解决MySQL 5.7中定位DDL被阻塞的问题

    这篇文章主要介绍了MySQL 5.7中如何定位DDL被阻塞的问题,在MySQL 5.7中,针对MDL,引入了一张新表performance_schema.metadata_locks,该表可对外展示MDL的相关信息,包括其作用对象,类型及持有等待情况。对此问题感兴趣的朋友参考下本文
    2018-08-08
  • 计算机二级考试MySQL知识点 mysql alter命令

    计算机二级考试MySQL知识点 mysql alter命令

    这篇文章主要为大家详细介绍了计算机二级考试MySQL知识点,详细介绍了mysql中alter命令的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • MySQL中VARCHAR和TEXT的区别小结

    MySQL中VARCHAR和TEXT的区别小结

    MySQL中VARCHAR和TEXT用于存储字符串,VARCHAR可变长度存储在行内,适合短文本;TEXT存储在溢出页,适合大文本,下面就来具体的了解一下两者的区别,感兴趣的可以了解一下
    2025-09-09
  • MySQL中MTR的概念

    MySQL中MTR的概念

    这篇文章主要介绍了MySQL中MTR的概念,帮助大家更好的理解和使用MySQL数据库,感兴趣的朋友可以了解下
    2020-11-11
  • 在MySQL中使用Sphinx实现多线程搜索的方法

    在MySQL中使用Sphinx实现多线程搜索的方法

    这篇文章主要介绍了在MySQL中使用Sphinx实现多线程搜索的方法,修改Sphinx的搜索引擎配置即可,需要的朋友可以参考下
    2015-06-06

最新评论