首页 > 其他分享 >自增主键去哪了?---一次开发过程中的思考

自增主键去哪了?---一次开发过程中的思考

时间:2024-09-05 16:03:19浏览次数:4  
标签:语句 自增 id --- 插入 now 主键

前情提要:

最近新接了一个需求,需要去创建两张表,其中有一张表需要根据业务id和业务类型建立唯一索引,对数据唯一性进行约束。

因为涉及到业务嘛,表结构就进行缩略了

表结构示例如下:

CREATE TABLE `example_table` ( 
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', 
    `business_id` bigint(20) unsigned NOT NULL COMMENT '业务ID', 
    `business_type` tinyint(3) unsigned NOT NULL COMMENT '业务类型,', 
    `del` tinyint(1) unsigned DEFAULT '0' COMMENT '删除标识,0表示未删除,1表示删除', 
    `creator` varchar(50) NOT NULL COMMENT '创建人PIN', 
    `modify_date` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 
    `create_date` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 
     PRIMARY KEY (`id`), 
     UNIQUE KEY `uk_business_id_and_type` (`business_id`,`business_type`)
 ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='示例表'

既然表建立好,那么就是发挥我们编码能力的时候了...此处省略一堆编码时间。

编码结束,自测结束,信心满满的找前端同学进行联调。

因为联调嘛,mock了很多同样的business_id和bussiness_type的数据,结果到了数据库,因为唯一索引的约束,报了一堆错误,插入都失败了。

终于调整了一下mock数据,插入成功了。

但是发生了一个比较神奇的现象

 


 

 

主键不是连续自增的了~~ 中间丢失的自增主键去哪了??

 

关于自增主键

自增主键是我们在设计数据库表结构时经常使用的主键生成策略,主键的生成可以完全依赖数据库,在新增数据的时候,我们只需要将主键设置为null,0或者不设置该字段,数据库就会为我们自动生成一个主键值。

首先,我们要知道 自增主键保存在哪里~

不同的引擎对于自增值的保存策略不同

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

2.InnoDB引擎的自增值,在MySQL5.7及之前的版本,自增值保存在内存里,并没有持久化。每次重启后,第一次打开表的时候,都会去找自增值的最大值max(id),然后将max(id)+步长(建表语句中的指定步长)作为这个表当前的自增值。在MySQL8.0版本,将自增值的变更记录在了redo log中,重启的时候依靠redo log恢复重启之前的值。

了解了自增主键的保存机制,再了解一下主键这个"自增"逻辑~

 


 

插入一条语句分配自增主键id值的流程如图所示。

自增主键不连续的情况

细心的小伙伴一定发现了~咦,这个ID=声明值的话,ID就可以能被随意指定了,那么ID就可能存在不是自增的情况了!

是的,这其实就是第一种自增主键不连续的情况。

第二种不连续的情况就是我们在联调中遇到的问题了

简单来做个测试,目前数据就像一开始的图一样,id自增到了24,下一个插入的应该是25,那么执行一条sql

insert into example_table  values (null,111,1,0,'mock',now(),now());

 


 

插入成功了一条数据,主键是连续自增的。

那么我们模拟一条错误的sql呢(`creator`字段指定错类型)~:

insert into example_table  values (null,112,1,0,mock,now(),now());

果然,执行sql 的时候报出异常:

 


 

继续执行一条正确的正常的sql,插入结果:

 


 

主键还是连续自增的。这个发生错误为什么自增主键还是连续的呢。我们模拟一下之前联调遇到的情况,插入一条 sql:

insert into example_table  values (null,112,1,0,'mock',now(),now());

因为id=26的数据buiness_id和bussiness_type 跟新插入的这条数据一样,那么肯定会因为唯一索引插入不成功,果然,执行结果如下:

 


 

那么,我们修改一下sql继续插入呢?

insert into example_table  values (null,113,1,0,'mock',now(),now())

 


 

主键发生了"断代",27的主键跑丢了...

明明都是sql插入的时候错误,为什么结果会有差异呢,有的时候主键会丢失,有的时候主键不会丢失呢,想要弄明白这个问题,就需要先明白一下一条sql的执行过程:

 


 

这里只是针对本文需要关注的点(相信小伙伴对这个执行过程肯定也是非常了解的

标签:语句,自增,id,---,插入,now,主键
From: https://www.cnblogs.com/Jcloud/p/18398648

相关文章

  • 【正点原子K210连载】第二十四章 LCD显示实验 摘自【正点原子】DNK210使用指南-CanMV
    第二十四章LCD显示实验本章将介绍初步介绍CanMV下LCD的使用。通过本章的学习,读者将学习到板载LCD的简单使用。本章分为如下几个小节:24.1lcd模块介绍24.2硬件设计24.3程序设计24.4运行验证24.1lcd模块介绍lcd模块是CanMV内置的模块,lcd模块用于驱动LCD进行一些简单的显示......
  • 【正点原子K210连载】第二十五章 LCD图片显示实验 摘自【正点原子】DNK210使用指南-Ca
    第二十五章LCD图片显示实验本章将介绍在LCD上的图片显示。通过本章的学习,读者将学习到LCD上图片的显示。本章分为如下几个小节:25.1lcd模块介绍25.2硬件设计25.3程序设计25.4运行验证25.1lcd模块介绍有关lcd模块的介绍,请见第24.1小节《lcd模块介绍》。25.2硬件设计25......
  • 使用vue-json-pretty和vue-json-schema-editor-visual封装一个可视化json数据编辑器及
    一、前言        最近做了一个需求,要求实现可以对json结构进行编辑保存及字段级别的权限管控,结合目前已有的轮子和当前项目的结构,决定使用vue-json-pretty和vue-json-schema-editor-visual来实现效果如下组件支持修改左侧json数据,自动生成右侧树。也支持修改右侧树......
  • 工程管理-Makefile
    简介       Linux的make程序用来自动化编译大型源码,很多时候,我们在Linux下编译安装软件,只需要敲一个make就可以全自动完成,非常方便。      make能自动化完成这些工作,是因为项目提供了一个Makefile文件,它负责告诉make,应该如何编译和链接......
  • 【时时三省】c语言例题----华为机试题<截取字符串>
    山不在高,有仙则名。水不在深,有龙则灵。                                    ----CSDN时时三省1,题目HJ46截取字符串描述输入一个字符串和一个整数k,截取字符串的前k个字符并输出数据范......
  • web-worker 利用多核 CPU 性能优化
    执行四个耗时任务,对比效果 <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metaname="viewport"content="width=device-width,initial-scale=1.0"/><title>WebW......
  • 软工homework2:个人项目-论文查重(Python)
    这个作业属于哪个课程广工计院计科34班软工这个作业要求在哪里作业要求这个作业的目标个人独立完成一次论文查重项目,完成项目后能够了解项目开发工程流程,学会使用PSP表格,完成性能分析以及测试等零、GitHub地址一、需求题目:论文查重描述如下:设计一个论文查重......
  • 性能优化---结果集优化
    举个比较直观的例子,我们都知道XML的表现形式是非常好的,那为什么还有JSON呢?除了书写要简单一些,一个重要的原因就是它的体积变小了,传输效率和解析效率变高了,像Google的Protobuf,体积就更小了一些。虽然可读性降低,但在一些高并发场景下(如RPC),能够显著提高效率,这是典型的对结......
  • 零拷贝---零拷贝---零拷贝
    硬盘上的数据,在发往网络之前,需要经过多次缓冲区的拷贝,以及用户空间和内核空间的多次切换。如果能减少一些拷贝的过程,效率就能提升,所以零拷贝应运而生。零拷贝是一种非常重要的性能优化手段,比如常见的Kafka、Nginx等,就使用了这种技术。我们来看一下有无零拷贝之间的区别。(1)......
  • web-worker 独立线程,性能优化
    ref:https://github.com/zjy4fun/web-worker分别使用主线程和worker线程处理一个耗时计算,看看对主线程上的UI渲染有什么影响 <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metaname="viewport"content=&q......