【MySQL】数据库的约束

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 【MySQL】数据库的约束


一、数据库的约束

1.1数据库的约束类型

image.gif编辑


1.2 null 约束

我们在创建表的时候在创建字段的时候可以指定某列不为空,

设计一个学生表 stud ,包含字段 id 类型 varchar(11) , 设置 not null , name 字段,类型 varchar(20)

image.gif编辑 表创建成功,这是插入两条记录观察一下:

image.gif编辑 我们可以观察到 插入第一条数据时,没有报错,当第二条记录企图插入一条 null 值时就报错了。

Column 'id' cannot be null —— 列“id”不能为空

image.gif编辑 当我们企图插入 只有姓名的字段的是否也报错了,字段“id”没有默认值,也是就表示我们不能在id 为空的情况下插入一行记录。show warnings; 可以查看当前的sql语法错误.


1.3 unique (唯一约束)

被指定的该列的记录属性不能重复,比如:每一个人都有自己独有的身份证号,是独一无二的数字组合,所以是不能重复的,在对字段添加该约束后,插入数据时,会根据该字段约束遍历表中的数据,确认没有该字段重复值后方可插入。

设计一个学生表 stud ,包含字段 id 类型 varchar(11) , 设置 unique约束 , name 字段 not null,类型 varchar(20)

image.gif编辑此时我们的 stud 表 id 字段的属性不可重复,name 字段属性 不可为空。

插入3条记录观察观察 : 1 张三, 1 ,李四 , 2, null;

image.gif编辑Duplicate entry '1' for key 'id' —— 键“id”的重复条目“1”

Column 'name' cannot be null —— 列“name”不能为空

image.gif编辑 所以最终只插入了一条记录。


1.4 primary key (主键约束)

有了约束之后,我们创建的表格就会越来越规范,根据博主上面所说,unique 约束字段不可重复,

not null 约束字段不可为空,那这次介绍的 主键约束 primary key 相当于 unique + not null 的约束效果,字段不为空且不可重复。

image.gif编辑重新构建了学生表 stud,并为 id 字段设置了主键约束,

插入3条记录观察观察 : 1 张三, 1 ,李四 , 2, null;

image.gif编辑Duplicate entry '1' for key 'PRIMARY' —— 键“PRIMARY”的重复条目“1”

Column 'name' cannot be null —— 列“name”不能为空

插入:null, 王五 或者 只插入 王五

image.gif编辑image.gif编辑 一个数据表只能有一个主键,一个主键约束也可以针对多个字段创建约束,这样就是多个字段处于不可为空且不可重复的状态。,数据库的主键,指的是一个列或多列的组合,其值能唯一地标识表中的每一行,通过它可强制表的实体完整性。主键主要是用与其他表的外键关联,以及文本记录的修改与删除。

主键的作用

1)保证实体的完整性;

2)加快数据库的操作速度

3)在表中添加新记录时,DBMS会自动检查新记录的主键值,不允许该值与其他记录的主键值重复。

4)DBMS自动按主键值的顺序显示表中的记录。如果没有定义主键,则按输入记录的顺序显示表中的记录。

对于整型(int)的主键,可以搭配自增长 auto_increment 使用,在插入数值时,不给主键字段赋值,主键字段就会根据上一条主键字段的值 + 1。

image.gif编辑插入2条记录观察观察 : 1 张三, null ,李四 。

image.gif编辑 可以看到第一条数据我们对主键 id 插入了数值 1 , 第二条记录,我们对主键 id 插入了数值 null ,正是因为我们对整型主键 id 设置了自增长,所以根据上一个字段的 id 值自增 + 1 = 2;

再插入2条记录观察观察 :100, 王五, null 赵六;

image.gif编辑 这个时候我们可以看到,这个自增属性当面对主动插入时就会失效,当需要自增时还是根据上一条记录的自增字段的值 + 1,所以是赵六的学号是 101, 而不是 3,这个自增属性就像是一个全局变量,可以记录字段的值,输入的时候就赋值,没有赋值的是否就自增。


1.5 default (默认值约束)

当我们对某个字段定义 default 约束的时候,我们在插入记录时,如果忽略该条记录,那么这条记录会按照设置的默认值填充。

例题:重新构建了学生表 stud,并为 sex 字段设置了默认值约束,默认值设置为“男”。

image.gif编辑 数据表构建完毕, 由上表可见,博主设置了三个字段,id , name ,sex ,并将 sex 字段设置默认值约束。

插入2条记录观察观察 : 1 张三 男, 2 李四 。

image.gif编辑image.gif编辑image.gif编辑 第一次我们对第一行记录的所有字段的数据进行插入数据,第二次我们只对第二行记录的 id ,name 字段进行设置,忽略了 sex 字段,但此时我们再对数据表 stud 的数据进行查询的时候发现 第二行记录的sex 字段填充了我们设置的默认值,男。


1.6 forelgn key (外键约束)

作为关系型数据库,外键约束在多表关系中是至关重要的,外键约束主要是关联其他表的主键或者唯一值。语法:

foreign key 【字段名】references 【主表】(主键字段或者唯一字段)

重点:

外键:针对子表,被约束的字段数据,受父字段数据的约束,不可以增改。

外键:针对父表,不能删除修改子表被约束的字段,两表之间约束是双向的。

举个例字:

image.gif编辑 我们先创建这两张表并为成绩表建立外键约束。

学生表 stud 的创建:

image.gif编辑成绩表 score 的创建:

image.gif编辑对子表score 的id 字段与 学生表的id字段产生了外键约束, 学生表为主表。

例题: 对stud 学生表插入数据,观察对score 成绩表有什么影响?

1 张三 男, 2 李四 男 , 3 王小六 女

image.gif编辑 语句正常执行没有任何变化。


例题: 对score 成绩表插入数据,观察对stud 学生表有什么影响?

1 80 99 90

2 74 80 99

3 98 78 69

4 50 65 56

image.gif编辑 当我们插入前三条数据的时候没有任何问题,现在插入第四条数据

image.gif编辑 直接报错,不必惊慌,错误1452(23000):不能添加或更新子行:外键约束失败(' school ')。' score_ibfk_1 ',约束' score_ibfk_1 '外键(' sc_id ')

这是报错信息,意思就是我们不能添加子行,因为受到了主表 stud, stu_id 字段的约束,

外键:针对子表,被约束的字段数据,受父字段数据的约束,不可以增改(改也只能是修改非约束字段)。通俗来讲就是在添加数据或者是修改数据之前,会先遍历父表,如果在父表中找不到约束的关键字,就不允许在子表中进行 insert / update 操作。

所以我们不能在成绩表中添加学号不在 stud学生表中的信息,在创建成绩表的时候我们也对 sc_id 字段设置了主键约束,所以呢, 要想在成绩表中添加记录需要满足以下要求,该记录 sc_id 字段不可为空且不可重复且该记录中的 sc_id字段值必须在 stud 学生表中存在。

此时我们成绩表的操作并不会对我们的主表造成影响。


例题: 对 stud 学生表删除数据修改数据,观察对 score 成绩表有什么影响?

先尝试删除 学生表中的一条记录:

image.gif编辑 错误1451(23000):不能删除或更新父行:外键约束失败(' school ')。' score_ibfk_1 ',约束' score_ibfk_1 '外键(' sc_id ')

报错提示的也非常明显,我们不能修改或删除父行, 因为两表之间存在外键约束。

外键:针对父表,不能删除修改子表被约束的字段,两表之间约束是双向的。

尝试修改学生表中的一条记录:将学生表中的学号为3 的同学的学号修改为 4

image.gif编辑 错误1451(23000):不能删除或更新父行:外键约束失败(' school ')。' score_ibfk_1 ',约束' score_ibfk_1 '外键(' sc_id ')

尝试修改学生表中的一条记录:将学生表中的学号为3 的同学姓名由 王小六 修改为 王六

image.gif编辑修改成功,只要不修改作为外键约束的字段,其他字段的值是可以被修改的。

总结:两表之间或者多表之间存在外键约束,作为主表来讲是不可以随便删除记录的, 那么如何保证数据的有效性呢,比如张三同学已经毕业了,那张三同学的信息就失效了。我们有两种做法,

一:是删除所有与主表与子表有对应字段外键关系的记录,主表是不可删除修改,子表是可以删除的, 我们先将子表中的约束记录删除,主表中的约束字段没有在子表中体现,那么主表中自然是允许删除的,但是有一个缺点就是你无法判断该字段建立了多少外键约束,非要删除的话,需要去找到这些子表,子表与子表之间有可能也存在外键约束,就会非常的复杂。

二:对主表添加可以判断数据是否有效的字段,比如是否毕业,当张三毕业时,我们将该字段设置为已毕业,然后再使用数据时是可以添加条件来约束,例如查找有所未毕业同学的信息,利用条件查询即可。


1.7 check 检查约束

在数据库中,CHECK 约束是指约束表中某一个或者某些列中可接受的数据值或者数据格式。

CHECK 约束可以应用于一个或者多个列,也可以将多个CHECK 约束应用于一个列。

当除去某个表时,对这个表的CHECK 约束也将同时被去除。

在更新表数据的时候,系统会检查更新后的数据行是否满足 CHECK 约束中的限定条件。MySQL 可以使用简单的表达式来实现 CHECK 约束,也允许使用复杂的表达式作为限定条件,例如在限定条件中加入子查询。

设置检查约束时要根据实际情况进行设置,这样能够减少无效数据的输入。

这个约束是啥意思呢,就是指定字段中的数据只能存在于设定的数据范围内,例如:sex 字段 ,

check (sex = "男" or sex = "女")

我们这样限定了之后,就不会出现其他的性别,比如说,"双性",不可能输入,只能存在 “男”或 “女”。比如我们限定了学号的范围 [1,10], 我们的id就只能在这个范围内。

image.gif编辑 表创建完毕,现在插入两条数据观察观察。

image.gif编辑image.gif编辑 但是我们会发现虽然我们期望 check 约束可以将数据限定来我们期望的范围内,但是在添加数据的时候还是可以超出这个限制,原因是因为,不同于SQL,在MYSQL中,CHECK只是一段可调用但无意义的子句。MySQL会直接忽略。 CHECK子句会被分析,但是会被忽略。

说白了就是没用,就是个摆烂的,博主寻思以为自己写错了,特意查询了一波资料,啥用没有,咦~


二、修改表的结构 (alter)

以上约束,可以看到博主都是在创建表的时候添加的( create ),除了我们在创建的时候添加约束,其实还有一种办法就是 修改表的结构 (alter),但是不建议使用吖,因为当我们对已有的表再去修改表的结构的时候会对表中原先存储的数据造成一定程度上的影响,那么我们要添加约束的时候使用修改字段的这个关键字即可 ,就像是创建时的那样,类型后面加上约束。

- 修改字段

   ALTER TABLE test.student MODIFY id_card varchar(30) 【约束】

-- 修改表结构

-- 添加字段

-- 新增一个叫做id_card的字段,它的类型是可变字符串且非空。

   ALTER TABLE test.student ADD id_card varchar(18) NOT NULL;

-- 修改字段

   ALTER TABLE test.student MODIFY id_card varchar(30)

-- 修改字段名

   ALTER TABLE test.student CHANGE id_card id_card1 char(10) not null;

-- 删除字段

   ALTER TABLE test.student DROP id_card1;

-- 修改表名  

   ALTER TABLE test.student RENAME test.stu;


本文图片由保护小周ღ的博客_CSDN博客-C语言,JavaEE,每日一题领域博主提供。

哎,这该死的友谊。

image.gif编辑


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
19天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
34 1
|
21天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
35 4
|
28天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
155 1
|
15天前
|
运维 关系型数据库 MySQL
安装MySQL8数据库
本文介绍了MySQL的不同版本及其特点,并详细描述了如何通过Yum源安装MySQL 8.4社区版,包括配置Yum源、安装MySQL、启动服务、设置开机自启动、修改root用户密码以及设置远程登录等步骤。最后还提供了测试连接的方法。适用于初学者和运维人员。
125 0
|
29天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
65 0
|
SQL Java 数据库连接
MySQL---数据库从入门走向大神系列(十五)-Apache的DBUtils框架使用
MySQL---数据库从入门走向大神系列(十五)-Apache的DBUtils框架使用
192 0
MySQL---数据库从入门走向大神系列(十五)-Apache的DBUtils框架使用
|
SQL 关系型数据库 MySQL
MySQL---数据库从入门走向大神系列(六)-事务处理与事务隔离(锁机制)
MySQL---数据库从入门走向大神系列(六)-事务处理与事务隔离(锁机制)
142 0
MySQL---数据库从入门走向大神系列(六)-事务处理与事务隔离(锁机制)
|
存储 SQL 关系型数据库
MySQL---数据库从入门走向大神系列(五)-存储过程
MySQL---数据库从入门走向大神系列(五)-存储过程
142 0
MySQL---数据库从入门走向大神系列(五)-存储过程
|
数据库
MySQL---数据库从入门走向大神系列(四)-子查询、表与表之间的关系(3)
MySQL---数据库从入门走向大神系列(四)-子查询、表与表之间的关系
203 0
MySQL---数据库从入门走向大神系列(四)-子查询、表与表之间的关系(3)
|
SQL 关系型数据库 MySQL
MySQL---数据库从入门走向大神系列(二)-用Java对MySQL进行增删改查
MySQL---数据库从入门走向大神系列(二)-用Java对MySQL进行增删改查
211 0
MySQL---数据库从入门走向大神系列(二)-用Java对MySQL进行增删改查