测试环境:MySQL版本:8.0
数据库表:
CREATE TABLE `test_t` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`c` int DEFAULT NULL COMMENT '唯一索引',
`d` int DEFAULT NULL COMMENT '普通字段',
PRIMARY KEY (`id`),
UNIQUE KEY `c` (`c`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
我们很多的业务设计依赖于主键id自增的连续性,来进行一些操作。但实际上,id自增主键不能保证连续递增的。
第一种情况:我们在执行新增SQL语句
insert into test values(null, 1, 1);
时,不设主键id的值时或是为null、0,主键id是自增的。不过你在中间大于自增id的值,这个连续性就会被打断。
如执行SQL是:insert into test_t values(21, 4, 1);
后续再自增的id是从21之后自增的,中间就连续不了。
第二种情况:唯一索引冲突
当执行该SQL语句时
insert into t values(null, 1, 1);
第一次执行新增是成功,第二次再次执行SQL语句时,就会出现错误。因为表中c字段是唯一索引,所以会出现Duplicate key error错误导致新增失败。
第三种情况:事务回滚
其实事务回滚原理也和上面一样,都是因为异常导致新增失败,但是自增值没有进行回退。
第四种情况:事批量插入
批量插入数据的语句,MySQL 有一个批量申请自增 id 的策略:
语句执行过程中,第一次申请自增 id,会分配 1 个;
1 个用完以后,这个语句第二次申请自增 id,会分配 2 个;
2 个用完以后,还是这个语句, 第三次申请自增 id,会分配 4 个;
依此类推,同一个语句去申请自增 id,每次申请到的自增 id 个数都是上一次的两倍。