MySQL8自增主键变化图文详解
作者:涛姐涛哥 发布时间:2024-01-25 19:08:38
一、简述
MySQL版本从5直接 * 到8,相信MySQL8一定会有很多令人意想不到的改进,如果不想只会CRUD可以看看。
比如系统表引擎的变化-全部换成事务型的InnoDB。
MySQL5.7系统部引擎
MySQL8系统引擎
上图可以看到,MySQL5.7的系统表引擎有MEMORY、InnnoDB和MyISAM三种,但MySQL8的系统表引擎都换成了InnoDB。MySQL8新特性还有很多,接下来进入正题康康它的自增主键。
二、MySQL自增主键
为什么MySQL8新特性会修改自增主键属性?
在MySQL8.0之前,自增主键 AUTO_INCREMENT 的值如果大于max(primary key) +1,那么在MySQL重启后,则会重置 AUTO_INCREMENT = max(primary key)+1 的值,这种现象在某些情况下会导致业务主键冲突或者其他难以发现的一些问题。
MySQL官网解释自增ID冲突问题
因为在MySQL5.7中,对于自增主键的分配规则是由InnoDB数据字典内部一个计数器来决定的,而该计数器维护在了内存中,并不会持久化到磁盘中,此时硬盘中并无数据,当数据库重启的时候,该计数器会被初始化为: auto_increment = max(primary key)+1。
如何解决自增主键冲突问题?
这个问题一直到MySQL8.0才解决。
8.0版本将会对 AUTO_INCREMENT 值进行持久化,所以即使MySQL重启后该值也不会改变。
即其将自增主键的计数器持久化到了重做日志中,每次计数器发生改变都会将其写入到重做日志中,如果这个时候数据库重启了,那么InnoDB数据字典会根据重做日志中的信息来初始化计数器的内存值,就可以恢复到了上次关闭数据库前的状态,通过自增ID持久化来避免8.0之前可能会出现的问题。
三、自增主键测试
分别在MySQL5和MySQL8上进行自增主键测试。
1、MySQL5.7自增主键
在MySQL5.7中的,这里我们先创建一个数据表,这个数据表中设置一个自增列。
CREATE TABLE t_test_auto_increment_tjt(
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`test_key` varchar(50) NOT NULL COMMENT '名称',
`test_value` varchar(50) DEFAULT NULL COMMENT '值',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='测试主键自增表';
然后向自增主键表中添加了4条记录,表中的四条添加的记录的id字段值就分别为: 1、2、3、4。
INSERT INTO t_test_auto_increment_tjt(id, test_key, test_value) VALUES
('0','吞噬星空','停更'),
('0','水斗大陆','可以停播了'),
('0','武神主宰','装B还得看尘少'),
('0','完美世界','yyds')
插入数据的SQL添加的是0,其实就是默认赋值,表 t_test_auto_increment_tjt 中的自增列是不可以添加0或者null的,那么这个时候表中的四条添加的记录的id字段值就分别为: 11、2、3、4。
接下来,将表中的id为4的字段删除。
DELETE FROM t_test_auto_increment_tjt WHERE id = 4
然后,继续在表中添加一条记录,执行之后我们可以发现,此时自增主键的ID结果是5。
INSERT INTO t_test_auto_increment_tjt(id, test_key, test_value) VALUES ('0','完美世界','yyds-YYDS')
因为我们前面已经将表中id为4的记录删除了,这个时候下一次自增的时候即使表中没有id为4的字段了,但是这个时候我们也不会添加4,而是添加5。其实这个时候就是自增主键的值auto_increment 大于了max(primary key)+1。
再接下来,将表中的id为5的记录删除。
DELETE FROM t_test_auto_increment_tjt WHERE id = 5
最后,重启MySQL数据库,再向表中添加一条记录。
INSERT INTO t_test_auto_increment_tjt(id, test_key, test_value) VALUES ('0','完美世界','yyds-YYDS-restart')
上图可以看到,重启后 重启后 重启后 执行的结果中添加的记录的id值为 : 4, 按之前的操作来看4和5已经被删除了,那么添加的就应该是6,为什么是4呢?
因为在MySQL5.7中,自增主键的分配规则是由InnoDB数据字典内部一个计数器来决定的,而该计数器维护在了内存中,并不会持久化到磁盘中,此时硬盘中并无数据,当数据库重启之后该计数器会被初始化为: auto_increment = max(primary key)+1,所以记录的id=4,而不是6。
2、MySQL8自增主键
在MySQL8中,按照上述MySQL5.7的操作步骤测试自增主键问题。
首先创建自增主键表、插入数据。
然后,删除数据、插入数据。
最后,重启 重启 重启 重启后插入数据。
一定要彻底关闭MySQL服务,然后重新启动。
重启后插入数据,测试自增主键ID的值?
来源:https://www.cnblogs.com/taojietaoge/p/16143104.html


猜你喜欢
- 先来了解下什么是数据库连接池数据库连接池技术的思想非常简单,将数据库连接作为对象存储在一个Vector对象中,一旦数据库连接建立后,不同的数
- pip install命令用于安装扩展库,由于安装扩展库需要从国外网站下载,速度较慢,可以使用-i选项设置临时使用国内的镜像网站。命令格式:
- 错误信息PS D:\parttime\python\django\guanxiangzhiji> python manage.py m
- 安装pip install requests发送网络请求import requestsr=requests.get('http://
- Python3.7 基于 pycryptodome 的AES加密解密、RSA加密解密、加签验签,具体代码如下所示:#!/usr/bin/en
- 本来想把之前对artTemplate源码解析的注释放上来分享下,不过隔了一年,找不到了,只好把当时分析模板引擎原理后,自己尝试写下的模板引擎
- 执行效果如下:from tkinter import *import urllib.requestimport gzipimport jso
- 前言虽然Python的标准库中 urllib2 模块已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Req
- 图片的上传上传图片使用了表单提交, 下面是html部分, enctype="multipart/form-data"表示
- django中,很多时候我们都需要有一个地方来进行更加详细的权限控制,例如说哪些用户可以访问哪些页面,检查登录状态等,这里的话就涉及到了中间
- 1. python中数字组成的列表转化为字符串或者一串数字f=[1,2,3,4]num=len(f)m='' #
- 高动态范围成像一、引言如今,大多数数字图像和成像设备每通道使用 8 位整数表示灰度,因此将设备的动态范围限制在两个数量级(实际上是 256
- 今天打算通过绘制正弦和余弦函数,从默认的设置开始,一步一步地调整改进,让它变得好看,变成我们初高中学习过的图象那样。通过这个过程来学习如何进
- 我们准备如下两个表,并插入数据。#分类CREATE TABLE IF NOT EXISTS `type` (`id` INT(10) UNS
- © 版权符号显示不清楚,就是那个圈C,在某些网站上就是显示太小,看不清楚。一开始还以为是字体大小的原因,调大以后,还是一样
- 这篇文章主要为大家详细介绍了python批量爬取下载抖音视频,具有一定的参考价值,感兴趣的小伙伴们可以参考一下项目源码展示:'
- 引言一般来说,很多时候我们面临这样一种情况,即我们需要运行时间记录器,它不断向我们显示当前时间或在给定的时间间隔内保持执行一定的代码和平,在
- 前言文接上回,我们已经使用gojs实现了一个最最最基本的树形布局。这次我们开始对图形的骨架进行一个内容展示上的丰富和显示风格上的美化。可以说
- innerHTML 属性的使用非常流行,因为他提供了简单的方法完全替代一个 HTML 元素的内容。另外一个方法是使用 DOM Level 2
- 1.sort()方法sort()是列表的方法,修改原列表使得它按照大小排序,没有返回值,返回NoneIn [90]: x = [4, 6,