MySQL 约束(入门版)

news2025/4/15 11:59:41

目录

一、约束的基本概念

二、约束演示

三、外键约束

(一)介绍

(二)外键约束语法

(三)删除/更新行为


一、约束的基本概念

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.coloradmin.cn/o/2333168.html

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

相关文章

系统与网络安全------Windows系统安全(11)

资料整理于网络资料、书本资料、AI&#xff0c;仅供个人学习参考。 制作U启动盘 U启动程序 下载制作U启程序 Ventoy是一个制作可启动U盘的开源工具&#xff0c;只需要把ISO等类型的文件拷贝到U盘里面就可以启动了 同时支持x86LegacyBIOS、x86_64UEFI模式。 支持Windows、L…

蓝桥杯 小蓝的操作(一维差分)

问题描述 一个数组 aa 中共包含 nn 个数&#xff0c;问最少多少次操作&#xff0c;可以让 aa 数组所有数都变成 11 。 操作的内容是&#xff1a;每次操作可以任选一个区间使得区间内的所有数字减 11 。 数据保证一定有解。 输入格式 第一行一个整数 nn 表示有 nn 个整数。 …

阿里云服务迁移实战: 02-服务器迁移

ECS 迁移 最简单的方式是 ECS 过户&#xff0c;不过这里有一些限制&#xff0c;如果原账号是个人账号&#xff0c;那么目标账号无限制。如果原账号是企业账号&#xff0c;则指定过户给相同实名认证的企业账号。 具体操作步骤可以参考官方文档 ECS过户 进行操作。 本文重点介绍…

protobuf的应用

1.版本和引用 syntax "proto3"; // proto2 package tutorial; // package类似C命名空间 // 可以引用本地的&#xff0c;也可以引用include里面的 import "google/protobuf/timestamp.proto"; // 已经写好的proto文件是可以引用 我们版本选择pr…

C++字符串操作详解

引言 字符串处理是编程中最常见的任务之一&#xff0c;而在C中&#xff0c;我们有多种处理字符串的方式。本文将详细介绍C中的字符串操作&#xff0c;包括C风格字符串和C的string类。无论你是C新手还是想巩固基础的老手&#xff0c;这篇文章都能帮你梳理字符串处理的关键知识点…

原理图设计准备:页面栅格模板应用设置

一、页面大小的设置 &#xff08;1&#xff09;单页原理图页面设置 首先&#xff0c;选中需要更改页面尺寸的那一页原理图&#xff0c;鼠标右键&#xff0c;选择“Schmatic Page Properties”选项&#xff0c;进行页面大小设置。 &#xff08;2&#xff09;对整个原理图页面设…

100道C++ 高频经典面试题带解析答案

100道C 高频经典面试题带解析答案 C作为一种功能强大且广泛应用的编程语言&#xff0c;在技术面试中经常被考察。掌握高频经典面试题不仅能帮助求职者自信应对面试&#xff0c;还能深入理解C的核心概念。以下整理了100道高频经典C面试题&#xff0c;涵盖基础知识、数据结构、面…

vue实现中英文切换

第一步&#xff1a;安装插件vue-i18n&#xff0c;npm install vue-i18n 第二步&#xff1a;在src下新建locales文件夹&#xff0c;并在locales下新建index.js、EN.js、CN.js文件 第三步&#xff1a;在EN.js和CN.js文件下配置你想要的字段&#xff0c;例如&#xff1a; //CN.js…

day31-贪心__56. 合并区间__ 738.单调递增的数字__968.监控二叉树 (可跳过)

56. 合并区间 合并区间&#xff0c;这道题和昨天的452. 用最少数量的箭引爆气球和435. 无重叠区间 也是类似的思路&#xff0c;我们需要先对所有vector按照左端点或者右端点进行排序。本题按照左端点进行排序。之后&#xff0c;如果前一段的右端点<后一段的左端&#xff0c…

【antd + vue】Modal 对话框:修改弹窗标题样式、Modal.confirm自定义使用

一、标题样式 1、目标样式&#xff1a;修改弹窗标题样式 2、问题&#xff1a; 直接在对应css文件中修改样式不生效。 3、原因分析&#xff1a; 可能原因&#xff1a; 选择器权重不够&#xff0c;把在控制台找到的选择器直接复制下来&#xff0c;如果还不够就再加&#xff…

GStreamer开发笔记(一):GStreamer介绍,在windows平台部署安装,打开usb摄像头对比测试

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://blog.csdn.net/qq21497936/article/details/147049923 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、O…

UE5,LogPackageName黄字警报处理方法

比如这个场景&#xff0c;淘宝搜索&#xff0c;ue5 T台&#xff0c;转为ue5.2后&#xff0c;选择物体&#xff0c;使劲冒错。 LogPackageName: Warning: DoesPackageExist called on PackageName that will always return false. Reason: 输入“”为空。 2. 风险很大的删除法&…

unity曲线射击

b站教程 using UnityEngine; using System.Collections;public class BallLauncher : MonoBehaviour {public float m_R;public NewBullet m_BulletPre;public Transform m_Target;private void Start(){StartCoroutine(Attack());}private void OnDestroy(){StopAllCoroutine…

freecad内部python来源 + pip install 装包

cmake来源&#xff1a; 只能find默认地址&#xff0c;我试过用虚拟的python地址提示缺python3config.cmake 源码来源&#xff1a; pip install 装包&#xff1a; module_to_install "your pakage" import os import FreeCAD import addonmanager_utilities as util…

Spring Boot 中集成 Knife4j:解决文件上传不显示文件域的问题

Spring Boot 中集成 Knife4j&#xff1a;解决文件上传不显示文件域的问题 在使用 Knife4j 为 Spring Boot 项目生成 API 文档时&#xff0c;开发者可能会遇到文件上传功能不显示文件域的问题。本文将详细介绍如何解决这一问题&#xff0c;并提供完整的解决方案。 Knife4j官网…

信噪比(SNR)的基本定义

噪比&#xff08;SNR&#xff09;是衡量信号质量的核心指标&#xff0c;定义为有效信号与背景噪声的比值&#xff0c;广泛应用于电子、通信、医学及生物学等领域。 一、定义 基本定义‌ SNR 是信号功率&#xff08;或电压&#xff09;与噪声功率&#xff08;或电压&#xff…

SpringBoot集成阿里云文档格式转换实现pdf转换word,excel

一、前置条件 1.1 创建accessKey 如何申请&#xff1a;https://help.aliyun.com/zh/ram/user-guide/create-an-accesskey-pair 1.2 开通服务 官方地址&#xff1a;https://docmind.console.aliyun.com/doc-overview 未开通服务时需要点击开通按钮&#xff0c;然后才能调用…

STM32 模块化开发指南 · 第 5 篇 STM32 项目中断处理机制最佳实践:ISR、回调与事件通知

本文是《STM32 模块化开发实战指南》第 5 篇,聚焦于 STM32 裸机开发中最核心也最容易被忽视的部分——中断服务机制。我们将介绍如何正确、高效地设计中断处理函数(ISR),实现数据与事件从中断上下文传递到主逻辑的通道,并构建一个清晰、可维护、非阻塞的事件通知机制。 一…

LabVIEW 中 JSON 数据与簇的转换

在 LabVIEW 编程中&#xff0c;数据格式的处理与转换是极为关键的环节。其中&#xff0c;将数据在 JSON 格式与 LabVIEW 的簇结构之间进行转换是一项常见且重要的操作。这里展示的程序片段就涉及到这一关键功能&#xff0c;以下将详细介绍。 一、JSON 数据与簇的转换功能 &am…

K8s常用基础管理命令(一)

基础管理命令 基础命令kubectl get命令kubectl create命令kubectl apply命令kubectl delete命令kubectl describe命令kubectl explain命令kubectl run命令kubectl cp命令kubectl edit命令kubectl logs命令kubectl exec命令kubectl port-forward命令kubectl patch命令 集群管理命…