MySQL 约束(入门版)

目录

一、约束的基本概念

二、约束演示

三、外键约束

(一)介绍

(二)外键约束语法

(三)删除/更新行为


一、约束的基本概念

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

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

3、分类

4、作用

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

        非空约束、唯一约束、主键约束、默认约束、检查约束主要用于限定对应字段的数据,在DDL (数据定义语言)中使用。

        外键约束用于建立两表之间的联系,在更新与删除对应内容时,两表发生对应的变化。

二、约束演示

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

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

对应的建表语句为:

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 '性别'
);

        在为字段添加约束时,我们只需要在字段之后加上约束的关键字即可如果有多个约束,则使用空格隔开。如果需要 id 字段是主键并且自增,则可以再使用关键字auto_increment。

        因为 id 列被定义为自增主键,所以插入数据时通常不需要显式地为该列指定值,数据库会自动为其生成一个唯一且递增的值。

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

--这两条可以正常执行
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','男');--第一条因为名字为null,第二条因为名字重复,所以这两条都不能正常执行
insert into tb_user(name,age,status,gender) values (null,19,'1','男');
insert into tb_user(name,age,status,gender) values ('Tom3',19,'1','男');--第一条可以正常执行,第二条和第三条因为年龄超过范围,所以不能正常执行
insert into tb_user(name,age,status,gender) values ('Tom4',80,'1','男');
insert into tb_user(name,age,status,gender) values ('Tom5',-1,'1','男');
insert into tb_user(name,age,status,gender) values ('Tom5',121,'1','男');--本条可以正常执行
insert into tb_user(name,age,gender) values ('Tom5',120,'男');

三、外键约束

(一)介绍

1、外键约束的基本概念        

        外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性。接下来,我们来看一个例子。

        左侧的emp表是员工表,里面存储员工的基本信息,包含员工的id、姓名、年龄、职位、薪资、入职日期、上级主管id、部门id。

        右侧的dept表是部门表,里面存储部门的基本信息,包括含部门的id与名字。

        在员工表emp中,部门id (dept_id)作为外键,关联部门表dept的主键id。

        具有外键的表被称为子表,外键所关联的表被称为父表所以上面的员工表emp是子表,而部门表dept是父表。

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

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

(二)外键约束语法

1、添加外键

(1)在建表时添加外键

create table 表名(
        字段名 数据类型,
        ...
        [ constraint ] [外键名称] foreign key (外键字段名) references 主表 (主表列名) 
);

        在创建外键约束时,constraint 关键字是可选的,它的主要作用是为外键约束命名,方便后续对外键约束进行管理,比如删除或者修改外键约束等操作

        如果不使用 constraint 关键字,数据库会自动为约束生成一个默认名称。

        如果需要查询这默认名称,可以通过查询 information_schema.table_constraints 系统表来获取外键约束的名称。以下是一个示例查询,用于查找 employees 表的外键约束名称:

select constraint_name
from information_schema.table_constraints
where table_schema = database() and table_name = 'employees'and constraint_type = 'foreign key';

        查询中,table_schema = database()用于指定当前数据库,table_name= employees'表示要查找employees表的外键约束,constraint_type = 'foreign key'确保只查找外键约束

(2)建表后额外添加

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出现了蓝色钥匙的形状,这是外键约束;字段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;
(三)增加外键约束后的删除/更新行为

1、具体的删除/更新行为

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

        如果没有规定对应的行为,默认行为是restrict,同时no action与其作用一致。

        cascade 的作用是级联。如果父表的内容被删除了,其对应子键所在行的数据也会被删除。如果父表的内容被更新了,其对应子键也会更新对应内容。

        在父键的内容被删除时,如果有对应外键,set null 会将其设置成 null,set default会将其设置为一个默认的值。

2、具体的语法

alter table 表名

add constraint 外键名称 foreign key (外键字段) references 主表名 (主表字段名)

on update (更新行为) on delete (删除行为);

3、具体演示

        由于 restrict 是默认行为,我们前面语法演示时,已经测试过了,就不再演示了,这里我们再演示其他的两种行为: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

        在进行测试之前,我们先需要删除上面建立的外键 fk_emp_dept_id。然后再通过数据脚本,将emp、dept表的数据恢复了。

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

        我们发现父表的记录是可以正常的删除的,父表的数据删除之后,再打开子表 emp,我们发现子表emp的dept_id字段,原来dept_id为1的数据,现在都被置为null了。这就是 set null 这种删除/更新行为的效果。
        
        以上即为MySQL 约束(入门版)的全部内容,创作不易,麻烦三连支持一下呗~  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/76431.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ISP】ISP pipeline(AI)

ISP Pipeline 全流程概览 ISP&#xff08;Image Signal Processing&#xff0c;图像信号处理&#xff09;流程通常从原始 Bayer 数据出发&#xff0c;经过一系列模块处理&#xff0c;逐步完成图像校正和增强&#xff0c;最终生成用于显示或编码的标准图像。常见处理模块包括&a…

【Rust开发】Rust快速入门,开发出Rust的第一个Hello World

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Google Chrome下载受限制的解决方案【方法指南】

在国内使用网络时&#xff0c;部分用户在尝试访问Google Chrome官网下载谷歌浏览器时&#xff0c;常常遇到网页无法打开或文件下载失败的情况。这种下载受限制的问题多由网络访问政策或DNS解析异常导致。为了正常获取Google Chrome的最新版安装程序&#xff0c;用户需要通过一些…

使用 new EventSource 实现前端实时通信

示例&#xff1a; eventSource单向通信 1. 什么是 EventSource&#xff1f; EventSource 是浏览器提供的一种实现服务器推送&#xff08;Server-Sent Events&#xff0c;简称 SSE&#xff09;功能的 API。它是基于 HTTP 协议的单向通信机制&#xff0c;可以通过服务器将实时数…

Android Input——查找并添加目标窗口(七)

在 Android 输入系统中,InputDispatcher 的核心职责之一是将输入事件正确地传递到目标窗口。上一篇文章我们介绍到 InputDispatcher 事件分发调用到 findFocusedWindowTargetsLocked() 函数查找焦点窗口,并将焦点窗口添加到目标窗口,这里我们继续往下看。 一、获取焦点窗口…

Spring Boot中Spring MVC相关配置的详细描述及表格总结

以下是Spring Boot中Spring MVC相关配置的详细描述及表格总结&#xff1a; Spring MVC 配置项详解 1. 异步请求配置 spring.mvc.async.request-timeout 描述&#xff1a;设置异步请求的超时时间&#xff08;单位&#xff1a;毫秒&#xff09;。默认值&#xff1a;未设置&…

HTTP GET 和 POST 请求有什么区别

HTTP 的 GET 和 POST 请求是两种常见的 HTTP 请求方法&#xff0c;它们有不同的特点和应用场景。以下是它们的主要区别&#xff1a; 1. 用途 GET&#xff1a;用于从服务器获取数据或资源。GET 请求会附带查询参数在 URL 中&#xff0c;通常用于请求数据&#xff0c;如加载网页…

从入门到精通【MySQL】 联合查询

文章目录 &#x1f4d5;摘要&#x1f4d5;1. 多表联合查询时MySQL内部原理✏️1.1 实例&#xff1a;一个完整的联合查询过程 &#x1f4d5;2. 内连接&#x1f4d5;3. 外连接&#x1f4d5;4. 自连接&#x1f4d5;5. 子查询✏️5.1 单行子查询✏️5.2 多行子查询✏️5.3 多列子查…

高可用之战:Redis Sentinal(哨兵模式)

参考&#xff1a;Redis系列24&#xff1a;Redis使用规范 - Hello-Brand - 博客园 1 背景 在我们的《Redis高可用之战&#xff1a;主从架构》篇章中&#xff0c;介绍了Redis的主从架构模式&#xff0c;可以有效的提升Redis服务的可用性&#xff0c;减少甚至避免Redis服务发生完…

加密≠安全:文件夹密码遗忘背后的数据丢失风险与应对

在数字化时代&#xff0c;保护个人隐私和数据安全变得尤为重要。许多人选择对重要文件夹进行加密&#xff0c;以防止未经授权的访问。然而&#xff0c;一个常见且令人头疼的问题也随之而来——文件夹加密密码遗忘。当你突然发现自己无法访问那些加密的文件夹时&#xff0c;那种…

WPS宏开发手册——附录

目录 系列文章7、附录 系列文章 使用、工程、模块介绍 JSA语法 JSA语法练习题 Excel常用Api Excel实战 常见问题 附录 7、附录 颜色序列&#xff1a;在excel中设置颜色&#xff0c;只能设置颜色序号&#xff0c;不能直接设置rgb颜色 1、黑色 (Black)…

C++基础精讲-02

文章目录 1.C/C申请、释放堆空间的方式对比1.1C语言申请、释放堆空间1.2C申请、释放堆空间1.2.1 new表达式申请数组空间 1.3回收空间时的注意事项1.4malloc/free 和 new/delete 的区别 2.引用2.1 引用的概念2.2 引用的本质2.3 引用与指针的联系与区别2.4 引用的使用场景2.4.1 引…

Spring Boot MongoDB 分页工具类封装 (新手指南)

Spring Boot MongoDB 分页工具类封装 (新手指南) 目录 引言&#xff1a;为何需要分页工具类&#xff1f;工具类一&#xff1a;PaginationUtils - 简化 Pageable 创建 设计目标代码实现 (PaginationUtils.java)如何使用 PaginationUtils 工具类二&#xff1a;PageResponse<…

MyBatis的缓存、逆向工程、使用PageHelper、使用PageHelper

一、MyBatis的缓存 缓存&#xff1a;cache 缓存的作用&#xff1a;通过减少IO的方式&#xff0c;来提高程序的执行效率。 mybatis的缓存&#xff1a;将select语句的查询结果放到缓存&#xff08;内存&#xff09;当中&#xff0c;下一次还是这条select语句的话&#xff0c;直…

java中的JNI调用c库

1. 简单demo 如果是在某个项目中有包名就需要自己找ai问问去改写下cmd命令去编译执行等 java文件&#xff08;HelloJNI.java&#xff09; public class HelloJNI {// 声明 native 方法public native void sayHello();// 加载本地库static {System.loadLibrary("hello&quo…

人工智能:GPT技术应用与未来展望

GPT(Generative Pre-trained Transformer)作为自然语言处理领域的代表性技术,近年来在各行业的实际应用中展现出广泛潜力。结合其技术特性与行业需求,以下是GPT的主要应用场景、案例分析及未来挑战的总结: 一、核心应用领域与案例 文本生成与内容创作 自动化内容生产:GPT…

前端笔记-ECMAScript语法概览

更多详细可以查看1.1 ES6 教程 | 菜鸟教程 这里我将大概记录ES与JS大概不一样的部分&#xff0c;方便联合记忆。 历史与关系 ECMAScript&#xff1a;是一种由 Ecma 国际组织制定的脚本语言规范&#xff0c;它是 JavaScript 的标准化版本。ECMAScript 为 JavaScript 提供了语…

操作主机的管理

1.在AD林范围内&#xff0c;有哪几个操作主机角色 架构主机&#xff08;Schema Master&#xff09; 功能&#xff1a;负责整个AD林中所有对象和属性的定义&#xff0c;是唯一可以更新目录架构的DC。架构更新会从架构主机复制到目录林中的所有其他域控制器。 作用范围&#xf…

【Linux】网络编程

目录 端口号 网络字节序 socket编程 接口 sockaddr结构 udp网络程序 创建套接字 绑定 接收 发送 客户端需要绑定吗&#xff1f; 客户端执行方法 本地环回地址 终端文件 代码 tcp网络程序 SOCK_STREAM 监听 查询网络信息 获取新连接 地址转换函数 客户端绑…

Go 语言中的select是做什么的

Go 语言中的 select 是做什么的 在 Go 语言中&#xff0c;select 语句是用于处理多个通道&#xff08;channel&#xff09;操作的一种控制结构。它类似于 switch 语句&#xff0c;但专门用于并发编程&#xff0c;允许 Goroutine 在多个通道上等待操作&#xff08;发送或接收&a…