Mysql之约束下篇

news2025/1/21 18:52:03

Mysql之约束下篇

  • 自增列(AUTO_INCREMENT)
    • 关键字
    • 特点和要求
    • 添加自增约束
    • 删除自增约束
    • Mysql8.0新特性-自增变量的持久化
  • FOREIGN KEY 约束
    • 关键字
    • 主表和从表/父表和子表
    • 特点
    • 添加外键约束
    • 约束等级
    • 删除外键约束
    • 面试问题
  • DEFAULT约束
    • 作用
    • 关键字
    • 添加默认值约束
    • 删除默认值约束
  • CHECK约束
    • 作用
    • 关键字
    • 案例
  • 面试问题

自增列(AUTO_INCREMENT)

自增列的作用:就是让某个字段的值自增自增

关键字

AUTO_INCREMENT

特点和要求

(1)一个表最多只能有一个自增长列
(2)当需要产生唯一标识符或顺序值时,可设置自增长
(3)自增长列约束的列必须是键列(主键列,唯一键列)
(4)自增约束的列的数据类型必须是整数类型
(5)如果自增列指定了 0 和 null,会在当前最大值的基础上自增;如果自增列手动指定了具体值,直接赋值为具体值。

添加自增约束

在数据类型后面或者约束后面加上AUTO_INCREMENT 就行
也分两种情况:
情况一:建表的时候,添加自增列
情况二:在建表之后,添加约束

错误演示

create table employee
(
eid int auto_increment,
ename varchar(20)
);
# ERROR 1075 (42000): Incorrect table definition; there can be only one auto column
and it must be defined as a key
create table employee(
eid int primary key,
ename varchar(20) unique key auto_increment
);
# ERROR 1063 (42000): Incorrect column specifier for column 'ename' 因为ename不是整数类
#情况一:
CREATE TABLE 表名
(
	数据段  数据类型 约束类型 AUTO_INCREMENT
)

案例

CREATE TABLE student8
(
id  INT PRIMARY KEY AUTO_INCREMENT,
name varchar(20)
)

DESC student8

在这里插入图片描述

情况二:

ALTER TABLE 表名称 
MODIFY 字段名 数据类型 AUTO_INCREMENT;

案例

CREATE TABLE student10
(
id INT PRIMARY KEY,
name varchar(20)
)

ALTER TABLE student10  MODIFY id  INT AUTO_INCREMENT

当然这里注意:
修改的时候,不必加上变量名的约束类型,只用加上变量名的约束类型就行。
在这里插入图片描述

删除自增约束

去掉AUTO_INCREMENT,就相当于删除自增约束


alter table 表名称 modify 字段名 数据类型; 
#去掉auto_increment相当于删除

案例

ALTER TABLE student10  MODIFY id INT;
DESC student10

在这里插入图片描述

Mysql8.0新特性-自增变量的持久化

Mysql8.0以前的版本

CREATE TABLE student11
(
id INT PRIMARY KEY AUTO_INCREMENT
)

INSERT INTO student11
VALUES(0),(0),(0),(0);

SELECT * FROM student11

在这里插入图片描述

当删除一4,然后再插入一个,插入的数变成了5

SELECT * FROM student11
DELETE FROM student11 WHERE id = 4
INSERT INTO student11 VALUES(0)
SELECT * FROM student11

在这里插入图片描述

此时重启数据库,然后在插入一个空值
在这里插入图片描述
此时插入的值却是4,但是根据逻辑此时插入的数应该会是6,那么为什么会出现这种情况呢?

主要原因是自增主键没有持久化。 在MySQL 5.7系统中,对于自增主键的分配规则,是由InnoDB数据字典内部一个 计数器 来决定的,而该计数器只在 内存中维护并不会持久化到磁盘中。当数据库重启时,该计数器会被初始化

在Mysql8.0以后的版本

在这里插入图片描述

从结果可以看出来,自增变量已经持久化了
MySQL 8.0将自增主键的计数器持久化到 重做日志 中。每次计数器发生改变,都会将其写入重做日志中。如果数据库重启,InnoDB会根据重做日志中的信息来初始化计数器的内存值

FOREIGN KEY 约束

作用:
限定某个表的某个字段的引用完整性
在这里插入图片描述

关键字

FOREIGN KEY

主表和从表/父表和子表

主表(父表):被引用的表,被参考的表
从表(子表):引用别人的表,参考别人的表

例如:员工表的员工所在部门这个字段的值要参考部门表:部门表是主表,员工表是从表。

例如:学生表、课程表、选课表:选课表的学生和课程要分别参考学生表和课程表,学生表和课程表是主表,选课表是从表。
在这里插入图片描述

特点

1.从表的外键列**,必须引用/参考主表的主键或唯一约束的列**
(因为因为被依赖/被参考的值必须是唯一的)
2.在创建外键约束时,如果不给外键约束命名,默认名不是列名,而是自动产生一个外键名(例如student_ibfk_1;),也可以指定外键约束)
3.创建(CREATE)表时就指定外键约束的话,先创建主表,再创建从表
4.删表时,先删从表(或先删除外键约束),再删除主表
5.当主表的记录被从表参照时,主表的记录将不允许删除,如果要删除数据,需要先删除从表中依赖该记录的数据,然后才可以删除主表的数据。
6.在“从表”中指定外键约束,并且一个表可以建立多个外键约束。
7.从表的外键列与主表被参照的列名字可以不相同,但是数据类型必须一样,逻辑意义一致。如果类型不一样,创建子表时,就会出现错误“ERROR 1005 (HY000): Can’t createtable’database.tablename’(errno: 150)”。
8.删除外键约束后,必须 手动 删除对应的索引

添加外键约束

情况一:建表的时候,添加约束

#语法格式:
create table 主表名称(
字段1 数据类型 primary key,
字段2 数据类型
);
create table 从表名称(
字段1 数据类型 primary key,
字段2 数据类型,
[CONSTRAINT <外键约束名称>] FOREIGN KEY(从表的某个字段) references 主表名(被参考字段)
);
#(从表的某个字段)的数据类型必须与主表名(被参考字段)的数据类型一致,逻辑意义也一样
#(从表的某个字段)的字段名可以与主表名(被参考字段)的字段名一样,也可以不一样
-- FOREIGN KEY: 在表级指定子表中的列
-- REFERENCES: 标示在父表中的列

案例

CREATE TABLE dep
(
dep_id  INT PRIMARY KEY,
dep_name varchar(20)
)

CREATE TABLE emp
(
emp_id INT PRIMARY KEY,
emp_name VARCHAR(20),
FOREIGN KEY(emp_id) REFERENCES dep(dep_id)
)

desc emp

注意:约束这里需要加上主表名,不需要加上从表名

在这里插入图片描述

情况二:建表之后,添加约束

REATE TABLE dep1
(
	dep1_id INT PRIMARY KEY
)

CREATE TABLE emp1
(
	emp1_id INT PRIMARY KEY 
)

ALTER TABLE emp1
ADD FOREIGN KEY(emp1_id) REFERENCES dep1(dep1_id) 

在这里插入图片描述

要注意: 要添加外键约束,必须要有唯一性约束或者主键约束

约束等级

1.Cascade方式 :在父表上update/delete记录时,同步update/delete掉子表的匹配记录
2.Set null方式 :在父表上update/delete记录时,将子表上匹配记录的列设为null,但是要注意子表的外键列不能为not null
3.No action方式 :如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作
4.Restrict方式 :同no action, 都是立即检查外键约束
5.Set default方式 (在可视化工具SQLyog中可能显示空白):父表有变更时,子表将外键列设置成一个默认的值,但Innodb不能识别

如果没有指定等级,就相当于Restrict方式。
对于外键约束,最好是采用: ON UPDATE CASCADE ON DELETERESTRICT 的方式

#语法格式:
create table 主表名称(
字段1 数据类型 primary key,
字段2 数据类型
);
create table 从表名称(
字段1 数据类型 primary key,
字段2 数据类型,
[CONSTRAINT <外键约束名称>] FOREIGN KEY(从表的某个字段) references 主表名(被参考字段)
)  ON UPDATE CASCADE ON DELETERESTRICT;

作用也就是同步更新,主表更新了,从表也更新
建表之后添加也一样,在之前的ALTER的语句后面加上,ON UPDATE CASCADE ON DELETERESTRICT,这句就行

删除外键约束

删除表的时候,要注意删除表的顺序,先删除从表再删除主表
删除外键约束时候,先删除删除外键约束,然后再删除索引
注意:索引只能手动删除

(1)第一步先查看约束名和删除外键约束
SELECT * FROM information_schema.table_constraints WHERE table_name = '表名称';#查看某个
表的约束名
ALTER TABLE 从表名 DROP FOREIGN KEY 外键约束名;2)第二步查看索引名和删除索引。(注意,只能手动删除)
SHOW INDEX FROM 表名称; #查看某个表的索引名
ALTER TABLE 从表名 DROP INDEX 索引名;
mysql> SELECT * FROM information_schema.table_constraints WHERE table_name = 'emp';
mysql> alter table emp drop foreign key emp_ibfk_1;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0


mysql> show index from emp;
mysql> alter table emp drop index deptid;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from emp;

面试问题

问题1:如果两个表之间有关系(一对一、一对多),比如:员工表和部门表(一对多),它们之间是否一定要建外键约束?
答:不是的

问题2:建和不建外键约束有什么区别?
答:建外键约束,你的操作(创建表、删除表、添加、修改、删除)会受到限制,从语法层面受到限制。例如:在员工表中不可能添加一个员工信息,它的部门的值在部门表中找不到。
不建外键约束,你的操作(创建表、删除表、添加、修改、删除)不受限制,要保证数据的 引用完整性 ,只能依 靠程序员的自觉 ,或者是 在Java程序中进行限定 。例如:在员工表中,可以添加一个员工的信息,它的部门指定为一个完全不存在的部门。

问题3:那么建和不建外键约束和查询有没有关系?
答:没有

MySQL 里,外键约束是有成本的,需要消耗系统资源。对于大并发的 SQL 操作,有可能会不适合。比如大型网站的中央数据库,可能会 因为外键约束的系统开销而变得非常慢 。所以, MySQL 允许你不使用系统自带的外键约束,在 应用层面 完成检查数据一致性的逻辑。也就是说,即使你不用外键约束,也要想办法通过应用层面的附加逻辑,来实现外键约束的功能,确保数据的一致性

DEFAULT约束

作用

给某个字段/某列指定默认值,一旦设置默认值,在插入数据时,如果此字段没有显式赋值,则赋值为默认值

关键字

关键字:DEFAULT

添加默认值约束

注意:说明:默认值约束一般不在唯一键和主键列上加

前面讲约束举了很多例子,用法都差不多,这里就不在举例了,说明下语法格式

情况一:建表的时候添加默认值约束

#语法格式:

create table 表名称(
字段名 数据类型 primary key,
字段名 数据类型 unique key not null,
字段名 数据类型 unique key,
字段名 数据类型 not null default 默认值,
);

情况二:建表之后,添加默认值约束

alter table 表名称 modify 字段名 数据类型 default 默认值;
#如果这个字段原来有非空约束,你还保留非空约束,那么在加默认值约束时,还得保留非空约束,否则非空约束就被删除了
#同理,在给某个字段加非空约束也一样,如果这个字段原来有默认值约束,你想保留,也要在modify语句中保留默认值约束,否则就删除了
alter table 表名称 modify 字段名 数据类型 default 默认值 not null;

删除默认值约束

alter table 表名称 modify 字段名 数据类型 ;#删除默认值约束,也不保留非空约束
alter table 表名称 modify 字段名 数据类型 not null; #删除默认值约束,保留非空约束

CHECK约束

作用

作用:检查某个字段的值是否符号xx要求,一般指的是值的范围
注意:MySQL5.7 可以使用check约束,但check约束对数据验证没有任何作用。添加数据时,没有任何错误或警告但是MySQL 8.0中可以使用check约束了。

关键字

CHECK约束

案例

这个CHECK约束不是特别重要,就简单了解下就行

CREATE TABLE temp
(
id INT AUTO_INCREMENT,
NAME VARCHAR(20),
age INT CHECK(age > 20),
PRIMARY KEY(id)
)

这个案例就是检查age是否是大于20的,
如果添加的信息age小于20那么就会添加信息失败
如果添加的信age大于20那么信息回添加成功

面试问题

面试1、为什么建表时,加 not null default ‘’ 或 default 0
答:不想让表中出现null值。

面试2、为什么不想要 null 的值 答: (1)不好比较。null是一种特殊值,比较时只能用专门的is null 和 is not
null来比较。碰到运算符,通常返回null。 (2)效率不高。影响提高索引效果。因此,我们往往在建表时 not null default’’ 或 default 0

面试3、带AUTO_INCREMENT约束的字段值是从1开始的吗?
在MySQL中,默认AUTO_INCREMENT的初始值是1,每新增一条记录,字段值自动加1。设置自增属性(AUTO_INCREMENT)的时候,还可以指定第一条插入记录的自增字段的值,这样新插入的记录的自增字段值从初始值开始递增,如在表中插入第一条记录,同时指定id值为5,则以后插入的记录的id值就会从6开始往上增加。添加主键约束时,往往需要设置字段自动增加属性。

面试4、并不是每个表都可以任意选择存储引擎? 外键约束(FOREIGN KEY)不能跨引擎使用。
MySQL支持多种存储引擎,每一个表都可以指定一个不同的存储引擎,需要注意的是:外键约束是用来保证数据的参照完整性的,如果表之间需要关联外键,却指定了不同的存储引擎,那么这些表之间是不能创建外键约束的。所以说,存储引擎的选择也不完全是随意的。

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

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

相关文章

Leetcode—445.两数相加II【中等】

2023每日刷题&#xff08;六十七&#xff09; Leetcode—445.两数相加II 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2…

k8s启动docker容器Error: Could not find or load main class ${start-class}报错

前行提要&#xff1a; 今天部署采集点服务&#xff08;docker项目&#xff09;发现报这个错误。 提出假设&#xff1a; 1&#xff0c;配置文件错误&#xff08;工程需要配置的东西比较多&#xff09; 之后开始一一排查&#xff0c;发现配置有问题&#xff0c;但是不是这个错误…

Blazor 混合开发_MAUI+Vue_WPF+Vue

MAUI&#xff0b;Vue 混合开发 背景混合开发的核心为什么必须使用 wwwroot 文件夹放置 Web 项目文件 创建 MAUI 项目创建 wwwroot 文件夹服务注册创建 _import.razor添加 Main.razor 组件修改 MainPage.xaml 文件 创建 WPF 项目创建 wwwroot 文件夹服务注册创建 _import.razor添…

DALL-E:Zero-Shot Text-to-Image Generation

DALL-E 论文是一个文本生成图片模型。 训练分为两个阶段 第一阶段&#xff0c;训练一个dVAE&#xff08;discrete variational autoencoder离散变分自动编码器&#xff09;&#xff0c;其将256 x 256的RGB图片转换为32 x 32的图片token。目的&#xff1a;降低图片的分辨率。图…

12 Vue3中使用v-if指令实现条件渲染

概述 v-if指令主要用来实现条件渲染&#xff0c;在实际项目中使用得也非常多。 v-if通常会配合v-else-if、v-else指令一起使用&#xff0c;可以达到多个条件执行一个&#xff0c;两个条件执行一个&#xff0c;满足一个条件执行等多种场景。 下面&#xff0c;我们分别演示这三…

最新国内AI绘画Midjourney绘画提示词Prompt分享

一、Midjourney绘画工具 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭…

Linux的常用命令及用法案例

概述 Linux 文件与目录结构 Linux 文件 Linux 系统中一切皆文件。 Linux 目录结构 VI/VIM 编辑器 是什么 VI 是 Unix 操作系统和类 Unix 操作系统中最通用的文本编辑器。 VIM 编辑器是从 VI 发展出来的一个性能更强大的文本编辑器。可以主动的以字体颜 色辨别语法的正确性…

GrayLog日志平台的基本使用-docker容器日志接入

1、/etc/docker/daemon.json中加入如下配置并重启服务 [rootlocalhost src]# cat /etc/docker/daemon.json { "registry-mirrors": ["https://dhq9bx4f.mirror.aliyuncs.com"], "log-driver": "gelf", "log-opts":…

Vue2+Vue3组件间通信方式汇总(2)------$emit

组件间通信方式是前端必不可少的知识点&#xff0c;前端开发经常会遇到组件间通信的情况&#xff0c;而且也是前端开发面试常问的知识点之一。接下来开始组件间通信方式第二弹------$emit,并讲讲分别在Vue2、Vue3中的表现。 Vue2Vue3组件间通信方式汇总&#xff08;1&#xff0…

linux基础06—windows下打不开wsl的ubuntu的子系统

一小时前还好好的&#xff0c;然后就打不开了&#xff0c;显示如下白板&#xff1a; &#xff08;1&#xff09;检查wsl 命令行输入&#xff1a;wsl -l -v 看是否有反应&#xff0c;如下所示&#xff1a; ctrlc退出&#xff0c;如果问题是控制流保护(Control Flow Guard)导致的…

WT2605C音频蓝牙语音芯片:单芯片实现蓝牙+MP3+BLE+电话本多功能应用

在当今的电子产品领域&#xff0c;多功能、高集成度成为了一种趋势。各种产品都需要具备多种功能&#xff0c;以满足用户多样化的需求。针对这一市场趋势&#xff0c;唯创知音推出了一款集成了蓝牙、MP3播放、BLE和电话本功能的音频蓝牙语音芯片——WT2605C&#xff0c;实现了单…

多用户商城系统哪个好,我的B2B2C电商系统选型之路

选择适合自己的B2B2C电商系统需要考虑多个因素&#xff0c;包括系统功能、易用性、扩展性、安全性和成本等。以下是一些常见的多用户商城系统供您参考&#xff1a; 1. 商淘云 基本情况&#xff1a;广州商淘信息科技有限公司旗下品牌&#xff0c;这家起步过程在国内商户中算比较…

Zabbix监控原理概括

一、zabbix工作流程 zabbix监控是将zabbix客户端要安装在被监控设备上负责收集数据&#xff0c;并将数据发送给zabbix服务端&#xff0c;将zabbix客户端接收或采集的数据存储在数据库中。 zabbix的数据收集分为两种模式&#xff1a; 1、主动模式 zabbix客户端主动向zabbix …

Arduino中LCD1602液晶显示器使用

目录 一、LCD160中字符串和计数显示 1、硬件介绍 2、引脚和接线说明 3、代码 二、LCD1602中显示超声波测量距离 1、硬件介绍 2、测试效果 3、代码 一、LCD160中字符串和计数显示 1、硬件介绍 1602液晶显示器 2、引脚和接线说明 单片机和测试模块接线 3、代码 //添加…

【clickhouse】在CentOS中离线安装clickhouse

一、下载地址 通过以下链接进行rpm安装包的下载 https://packages.clickhouse.com/rpm/stable/ 根据需求下载对应版本 注意&#xff1a;ClickHouse 20.8.2.3版本新增加了 MaterializeMySQL 的 database 引擎&#xff0c;该 database 能映射到 MySQL 中的某个 database&#…

如何恢复SD卡剪切丢失的照片

SD卡照片剪切丢失是常见问题&#xff0c;这通常是由于多种原因造成的。一方面&#xff0c;SD卡可能存在质量问题&#xff0c;如制造缺陷或使用了低质量的存储芯片。另一方面&#xff0c;错误的操作方式也可能导致照片丢失&#xff0c;如没有先进行备份就直接剪切照片&#xff0…

前端常用的开发工具

前端常用的开发工具&#x1f516; 文章目录 前端常用的开发工具&#x1f516;1. Snipaste--截图工具2. ScreenToGif--gif图片录制3. Typora--Markdown编辑器4. notepad--文本代码编辑器5. uTools--多功能工具6. EV录屏--录屏软件7. Xmind--思维导图8. Apifox -- 接口调试9. Tor…

vue element plus 管理系统路由菜单简要设计(后端获取菜单)

1 需求 管理系统“菜单”由后端接口返回&#xff0c;前端需要根据后端返回的“菜单”数组&#xff0c;构造路由&#xff0c;渲染侧栏菜单有些菜单是子菜单&#xff0c;有对应的路由&#xff0c;但是不在侧栏显示&#xff08;比如一些详情页面&#xff09; 注&#xff1a;这里的…

nmap端口扫描工具安装和使用方法

nmap&#xff08;Network Mapper&#xff09;是一款开源免费的针对大型网络的端口扫描工具&#xff0c;nmap可以检测目标主机是否在线、主机端口开放情况、检测主机运行的服务类型及版本信息、检测操作系统与设备类型等信息。本文主要介绍nmap工具安装和基本使用方法。 nmap主…

循环神经⽹络中的梯度算法GRU

1. 什么是GRU 在循环神经⽹络中的梯度计算⽅法中&#xff0c;我们发现&#xff0c;当时间步数较⼤或者时间步较小时&#xff0c;**循环神经⽹络的梯度较容易出现衰减或爆炸。虽然裁剪梯度可以应对梯度爆炸&#xff0c;但⽆法解决梯度衰减的问题。**通常由于这个原因&#xff0…