MySQL主键自增

492 字
2 分钟
MySQL主键自增

这里只记录 innodb 引擎的实现逻辑

MySQL ≤ 5.7#

自增值保存在内存中,在第一次打开表时,会找到 max(id),会将 max(id) + 1 作为这个表当前的自增值。所以,如果 mysql 重启,可能会导致自增值变化。举例 table x id 如下,当前最大 id 为10,如果立马删除 id = 10 的数据,然后重启 mysql 实例,重启后,table x 的自增值会重新变为10(max(id) + 1 = 9 + 1)。

table x

id
1
2
9
10

MySQL ≥ 8.0#

自增值会在 redo log 中持久化,mysql 重启后会从 redo log 中恢复自增值

MySQL 主键自增值修改机制#

id_increament_test 初始情况

Terminal window
mysql> show create table id_increament_test;
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id_increament_test | CREATE TABLE `id_increament_test` (
`id` int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  1. 插入时,id = 0 或者 nul,主键id会按照当前自增值来赋值
insert into id_increament_test values (0),(null)
Terminal window
mysql> select * from id_increament_test;
+-----+
| id |
+-----+
| 1 |
| 2 |
+-----+
mysql> show create table id_increament_test;
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id_increament_test | CREATE TABLE `id_increament_test` (
`id` int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  1. 假设当前自增值为 Y,插入时,如果指定了id值 X(X ≠ 0,并且 X值不与数据库中的任何值冲突),分为两种情况:
    1. X < Y,插入数据 id = X,自增值不变
insert into id_increament_test values (-1)
Terminal window
mysql> select * from id_increament_test;
+-----+
| id |
+-----+
| -1 |
| 1 |
| 2 |
+-----+
mysql> show create table id_increament_test;
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id_increament_test | CREATE TABLE `id_increament_test` (
`id` int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
2. X ≥ Y,插入数据 id = X,自增值变为 Y = X+(自增步长)
insert into id_increament_test values (100)
Terminal window
mysql> select * from id_increament_test;
+-----+
| id |
+-----+
| -1 |
| 1 |
| 2 |
| 100 |
+-----+
mysql> show create table id_increament_test;
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id_increament_test | CREATE TABLE `id_increament_test` (
`id` int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

📎 参考文章#

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

MySQL主键自增
https://blog.sephy.top/posts/mysql主键自增/
作者
虾米
发布于
2024-12-30
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
虾米
coder
分类
标签
站点统计
文章
61
分类
4
标签
52
总字数
64,663
运行时长
0
最后活动
0 天前
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.13.9
文章许可
CC BY-NC-SA 4.0