Mysql中自增主键是如何工作的

自增主键的特点是当表中每新增一条记录时,主键值会根据自增步长自动叠加,通常会将自增步长设置1,也就是说自增主键值是连续的。那么MySQL自增主键值一定会连续吗?今天这篇文章就来说说这个问题,看看什么情况下自增主键会出现不连续?

1.数据准备

drop TABLE increnment_test;
-- 创建包含自增主键的表  
CREATE TABLE increnment_test (  id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,  col1 INT(11) NOT NULL,col2 INT(11) NOT NULL,col3 INT(11) NOT NULL,UNIQUE KEY (col1)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

2.自增值存储机制

1.MyISAM 引擎的自增值保存在数据文件中。

2.Innodb 引擎

● 在 MySQL 5.7 及之前的版本,自增值保存在内存里。每次重启后,第一次打开表的时候,都会去找自增值的最大值 max(id),然后将 max(id) + 1 作为这个表当前的自增值。
● 在 MySQL 8.0 版本,将自增值的变更记录在了 redo log 中,重启的时候依靠 redo log 恢复重启之前的值。

-- 1.往increnment_test表中插入2条数据
INSERT INTO increnment_test (col1, col2, col3) VALUES    (1, 1, 1),    (2, 2, 2);-- 2.此时id值为2,AUTO_INCREMENT值为3。我们删除id为2的记录
delete from increnment_test where id = 2;-- 3.立马重启实例,重新插入记录。此时id为2。
INSERT INTO increnment_test (col1, col2, col3) VALUES    (2, 2, 2);-- 4.不重启实例,删除id为2的记录后,重新插入数据,id应为3。

3.自增值修改机制

在MySQL中,可以使用AUTO_INCREMENT关键字来指定ID字段为自增ID字段。当向表中插入一条记录时,MySQL将自动为该记录的ID字段生成一个新的自增ID值,并将该值保存到该记录的ID字段中。具体规则如下:

● 如果ID字段未指定具体的值,则将当前AUTO_INCREMENT值并将其填入自增字段,并生成新的自增值
● 如果ID字段已指定具体的值,则直接使用指定的值作为 ID 字段的值,而不会生成新的 AUTO_INCREMENT 值。

根据要插入的值和当前自增值的大小关系,自增值的变更结果也会有所不同。

● 如果插入值小于当前自增值,那么直接使用插入值填入ID字段,自增值不变;
● 如果插入值大于当前自增值,那么除了直接使用插入值填入ID字段外,自增值需修改为插入值+1;

上述”插入值+1‘不是直接使用”插入值“+1,是auto_increment_offset(自增初始值)以 auto_increment_increment(自增步长)为步长,持续累加,直到找到大于插入值的值,作为新的自增值。

4.自增值修改流程

上述我们了解了自增值的存储机制与修改机制,自增值修改是在哪个环境呢?那需要了解自增值修改流程。

INSERT INTO increnment_test (col1, col2, col3) VALUES (3, 3, 3);

以上述SQL为例,我们假如数据库里已经有2条数据了,它的执行流程如下:

● 执行器调用 InnoDB 引擎接口将分析器优化后的SQL传入,并将值(3,3,3)一起传过去。
● InnoDB 发现用户没有指定自增 id列,会先获取表increnment_test当前的自增值3;
● 将ID列补充完整,并且将自增值填入(3,3,3,3)
● 然后将表的自增值改成4;
● 继续执行插入数据操作;

自增字段值的生成是由存储引擎自动完成的,而不是由优化器完成的。因此,在执行 SQL 语句时,即使未指定自增字段列,也不会对性能产生任何影响。

5.导致自增值不连续的原因

5.1 唯一键冲突

比如increnment_test中已经存在了col1为3的记录,我们继续插入col1为3的记录,此时会出现唯一键冲突插入报错,但是没有将自增值再改回去。重新插入col1为4的值,此时对应的id为5;
如下操作流程:

5.1.1.检查数据

select * from increnment_test;

在这里插入图片描述

5.1.2.插入col1为3的数据

INSERT INTO increnment_test (col1, col2, col3) VALUES    (3, 3, 3);

5.1.3.插入col1为4的记录

INSERT INTO increnment_test (col1, col2, col3) VALUES    (4, 4, 4);
select * from increnment_test;

在这里插入图片描述

5.2.事务回滚

开启一个事务插入col1为6的数据,然后进行回滚。回滚后重新插入col1为6的记录,此时col1为6对应的id值为7。

BEGIN;    
INSERT INTO increnment_test (col1, col2, col3) VALUES      (6, 6, 6);   
ROLLBACK; BEGIN;    
INSERT INTO increnment_test (col1, col2, col3) VALUES      (6, 6, 6);   
COMMIT;

在这里插入图片描述

5.3.批量插入数据

对于批量插入数据的语句,MySQL有一个批量申请自增 id 的策略:

● SQL语句执行过程中,第1次申请自增 id,会分配 1 个;
● 1 个用完以后,第2次申请自增 id,会分配 2 个;
● 2 个用完以后,第3次申请自增 id,会分配 4 个;

依此类推,同一个语句去申请自增 id,每次申请到的自增id个数都是上一次的两倍。

drop table increnment_test2;
create table increnment_test2 like increnment_test;INSERT INTO increnment_test2 (col1, col2, col3) SELECTcol1, col2, col3 FROM increnment_test;INSERT INTO increnment_test2 (col1, col2, col3)
VALUES (8, 8, 8);  SELECT * FROM increnment_test2;

在这里插入图片描述

因为increnment_test2表中批量插入了5条数据,按照自增ID的批量申请策略,5条数据分3次进行申请:
第1次:id-1
第2次:id-2、3
第3次:id-4、5、6、7
由于只有5条记录,所以只使用了4、5被浪费了。当我们在次插入数据时,AUTO_INCREMENT从8开始。

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

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

相关文章

第三阶段学习beiqi3

滑行回馈力矩给定修改力矩 if(1 Vehicle_cmd.cmdmode.data.slip_feedback_flag)//滑行回馈{motor_regen_power EV_MCU_Para.field.Motor_regen_power_slip_level;//滑行固定功率在 10kw *****11.22 这里除去2 5kw motor_regen_trq_lmt _IQmpyI32(motor_regen_power, 9550)…

postman设置接口关联这样做,薪资直接涨3k

postman设置接口关联 在实际的接口测试中,后一个接口经常需要用到前一个接口返回的结果, 从而让后一个接口能正常执行,这个过程的实现称为关联。 在postman中实现关联操作的步骤如下: 1、利用postman获取上一个接口指定的返回值…

kubernetes资源管理

kubernetes资源管理 文章目录 kubernetes资源管理1.资源管理介绍2.YAML语言介绍3.资源管理方式3.1 命令式对象管理3.2 命令式对象配置3.3 声明式对象配置扩展:kubectl在node节点上运行 1.资源管理介绍 在kubernetes中,所有的内容都抽象为资源&#xff0…

c语言编程(模考3)统计字符串中数字字符的个数

统计字符串中数字字符的个数 #include<stdio.h> int main(){char inputString[100];int digitCount 0;printf("请输入一个字符串&#xff1a;");scanf("%s",inputString);for(int i0;inputString[i]!\0;i){if (inputString[i]>0&&inpu…

jQuery的学习(一篇文章齐全)

目录 Day29 jQuery 1、jQuery介绍 2、jQuery的选择器 2.1、直接查找 2.2、导航查找 3、jQuery的绑定事件 案例1&#xff1a;绑定取消事件 案例2&#xff1a;模拟事件触发 4、jQuery的操作标签 tab切换案例jQuery版本&#xff1a; 案例1&#xff1a; 案例2&#xff…

Thread的常用方法

一&#xff0c;常用方法 二&#xff0c;案例 父类&#xff1a; package ThreadLianXi;import ThreadLianXi.ZhiLeiA;public class Name {public static void main(String[] args)throws Exception{Thread t1 new ZhiLeiA("1号");//修改名字t1.setName("1号&quo…

中国最常用的制作报表的软件有哪些?

​随着信息化时代的浪潮席卷而来&#xff0c;报表制作软件已经成为了企业管理中的得力助手。在中国的大地上&#xff0c;有许多优秀的报表制作软件&#xff0c;而本文将为您揭示五位佼佼者&#xff0c;其中更以VeryReport报表软件为首选。 编辑搜图 请点击输入图片描述&#x…

华为昇腾开发板共享Windows网络上网的方法

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> 具体参考文章&#xff1a;linux(内网&#xff09;通过window 上网。具体是两步&#xff1a;一是在windows上设置internet连接共享。二是打开Atlas 200I D…

最长连续序列[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给定一个未排序的整数数组nums&#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。请你设计并实现时间复杂度为O(n)的算法解决此问题。 示例 1&#xff1a; 输入&#xff1a;nums […

【性能测试学习】2023最有效的7大性能测试技术(建议收藏)

进入互联网时代&#xff0c;性能测试显得越来越重要&#xff0c;移动应用、web应用和物联网应用都需要进行性能测试和性能调优&#xff0c;而进行性能和负载测试会产生了大量的数据&#xff0c;这些数据难以分析。除了数据分析&#xff0c;我们还会遇到其它一些困难和挑战。 今…

win10 eclipse安装教程

前言&#xff1a;安装eclipse之前必须安装JDK&#xff0c;JDK是编译环境&#xff0c;eclipse是集成开发平台。 一、JDK的安装 Java Development Kit 简称 JDK (一). 官方下载地址&#xff1a; Java Archive Downloads - Java SE 8u211 and later (oracle.com) 找到&#xf…

关于的Java线程池,简解

Java线程池是一种常见的多线程编程技术&#xff0c;它可以在执行任务时复用已创建的多个线程&#xff0c;并且可以控制同时运行的线程数以避免资源占用过多的问题。 线程池可以用于处理需要频繁创建并执行线程的情况&#xff0c;例如在需要执行大量短期异步任务的环境中。通过使…

2020年计网408

第33题 下图描述的协议要素是&#xff08; &#xff09;。I. 语法 II. 语义 III. 时序 A. 仅 I B. 仅 II C. 仅 III D. I、II 和 III 本题考察网络协议三要素的相关知识。 网络协议的三要素分别是语法、语义、同步&#xff08;时序&#xff09;。语法&#xff1a;定义收发双…

10月起个税系统升级,3个月个税零申报将收到提示

近日&#xff0c;自然人电子税务局扣缴端升级了&#xff0c;升级后对于工资薪金收入连续三个月为零的纳税人&#xff0c;系统会自动出现以下提示。这个提示主要为了避免企业长期对已经离职的员工进行零申报&#xff0c;导致数据不准确和资源浪费。HR在申报个税时&#xff0c;一…

OSG文字-渐变文字(4)

渐变文字(osgText::FadeText类)继承自osgText::Text类继承关系图如图9-6所示 图9-6 osgText::FadeText的继承关系图 从继承关系图中可以看出&#xff0c;它继承自osgText::Text类&#xff0c;因此&#xff0c;它具备一般文字属性的设置方法这里不再重复说明。创建渐变文字与一般…

PHP 安装

您需要做什么&#xff1f; 为了开始使用 PHP&#xff0c;您可以&#xff1a; 找一个支持 PHP 和 MySQL 的 Web 主机在您自己的 PC 机上安装 Web 服务器&#xff0c;然后安装 PHP 和 MySQL 使用支持 PHP 的 Web 主机 如果您的服务器支持 PHP&#xff0c;那么您不需要做任何事情…

​软考-高级-系统架构设计师教程(清华第2版)【第14章 云原生架构设计理论与实践(P496~526)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第14章 云原生架构设计理论与实践&#xff08;P496~526&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

Java排序实战:如何高效实现电商产品排序

在当今的数字化时代&#xff0c;电子商务已成为人们日常生活的重要组成部分。消费者可以在电商平台上浏览和购买来自全球的商品&#xff0c;这无疑为我们的生活带来了极大的便利。然而&#xff0c;随着电商平台的规模不断扩大&#xff0c;商品数量的急剧增加&#xff0c;如何对…

[点云分割] 区域增长分割

效果&#xff1a; 原始数据 分割结果 代码&#xff1a; #include <iostream> #include <vector> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> // 各种点云数据类型 #include <pcl/search/search.h> #include <pcl/search/kdtr…

Vue3 官推的状态管理 Pinia

Vue3 官推的状态管理 Pinia 一、Pinia是什么&#xff1f;二、Pinia的特点三、Pinia的使用1.npm install pinia -s2.创建pinia实例3.注册到App实例上4.模块化管理5.组件中使用6.路由中使用1.创建全局路由守卫2.全局守卫中使用全局状态 四、修改数据 $patch五、重置数据 $reset六…