日常工作中,是否遇到明明设置了自增主键,结果自增ID却是非连续性的情况呢,今天就通过测试来复现这种情况
测试表以及相关参数设置如下:
mysql> show variables like '%auto_increment%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
+--------------------------+-------+
2 rows in set (0.01 sec)
mysql> show create table test2\G
*************************** 1. row ***************************
Table: test2
Create Table: CREATE TABLE `test2` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_b` (`b`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
1 row in set (0.00 sec)
mysql> insert into test2(a,b) values(1,1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test2;
+----+------+------+
| id | a | b |
+----+------+------+
| 1 | 1 | 1 |
+----+------+------+
1 row in set (0.00 sec)
mysql> insert into test2(a,b) values(2,1);
ERROR 1062 (23000): Duplicate entry '1' for key 'idx_b'
mysql>
mysql> insert into test2(a,b) values(2,2);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test2;
+----+------+------+
| id | a | b |
+----+------+------+
| 1 | 1 | 1 |
| 3 | 2 | 2 |
+----+------+------+
2 rows in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test2(a,b) values(3,3);
Query OK, 1 row affected (0.01 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> insert into test2(a,b) values(3,3);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test2;
+----+------+------+
| id | a | b |
+----+------+------+
| 1 | 1 | 1 |
| 3 | 2 | 2 |
| 5 | 3 | 3 |
+----+------+------+
3 rows in set (0.00 sec)
mysql> insert into test2 values(100,4,4);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test2;
+-----+------+------+
| id | a | b |
+-----+------+------+
| 1 | 1 | 1 |
| 3 | 2 | 2 |
| 5 | 3 | 3 |
| 100 | 4 | 4 |
+-----+------+------+
4 rows in set (0.00 sec)
mysql> show create table test2\G
*************************** 1. row ***************************
Table: test2
Create Table: CREATE TABLE `test2` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_b` (`b`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
1 row in set (0.00 sec)
mysql> select * from test2;
+-----+------+------+
| id | a | b |
+-----+------+------+
| 1 | 1 | 1 |
| 3 | 2 | 2 |
| 5 | 3 | 3 |
| 100 | 4 | 4 |
+-----+------+------+
4 rows in set (0.00 sec)
mysql> create table test3 like test2;
Query OK, 0 rows affected (0.08 sec)
mysql>
mysql> insert into test3(a,b) select a,b from test2;
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from test3;
+----+------+------+
| id | a | b |
+----+------+------+
| 1 | 1 | 1 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
| 4 | 4 | 4 |
+----+------+------+
4 rows in set (0.00 sec)
mysql> insert into test3(a,b) values(5,5);
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> select * from test3;
+----+------+------+
| id | a | b |
+----+------+------+
| 1 | 1 | 1 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
| 4 | 4 | 4 |
| 8 | 5 | 5 |
+----+------+------+
5 rows in set (0.00 sec)
***************************************************
备注1:这里的批量插入是指包含的语句类型是 insert … select、replace … select 和 load data等,不包括insert into values(),(),();
备注2:假设test2有N条数据(2的x次方 <= N < 2的x+1次方),将test2非id列插入test3中,test3插入的下一条数据的id值为2的x+1次方。example:test2中有33条数据,33>32(2的5次方,33<64(2的6次方)),往test3插入的34条数据的id为64