MySQL 自增主键不连续测试

日常工作中,是否遇到明明设置了自增主键,结果自增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)
  • round1(数据冲突所致)
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)

  • round2(事务回滚所致)
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)
  • round3(手动指定自增ID所致)
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)
  • round4(批量insert所致)
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

你可能感兴趣的:(MySQL)