主键自增理解
自增主键:
InnoDB引擎的自增值,其实是保存在内存里,并且到了MySQL8.0版本之后,才有了自增值持久化的能力。也就是实现了如果发生重启后,表的自增值可以恢复为MySQL重启前的值。
在MySQL5.7及之前的版本,自增值保存在内存里,并没有持久化。每次重启后,第一次打开表的时候,都会去找自增值的最大值max(id),然后将max(id)+1作为这个表当前的自增值。
在MySQL8.0版本,将自增值的变更记录在redo log日志中,重启的时候依靠redo log日志恢复重启之前的值。
自增值修改机制:
1.如果插入数据时id字段指定为0、null、或未指定值,那么就把这个表当前的AUTO_INCREMENT值填到自增字段;
2.如果插入数据时id字段制定了具体的值,就直接使用语句里指定的值
自增值新增机制:
1.如果准备插入的值>=当前自增值,新的自增值就是准备插入的值+1;
2.否则,自增值不变。
为什么自增主键不连续
-
在MySQL 5.7及之前的版本,自增值保存在内存里,并没有持久化 -
事务回滚(自增值不能回滚,因为并发插入数据时,回滚自增ID可能会造成主键冲突) -
唯一键冲突(由于表的自增值已变,但是因为主键发生冲突没插进去,下一次插入主键值=现在变化了的自增值+1,所以不连续)
代码实践:
create table xuehu(
id int primary key auto_increment,
name varchar(10) unique ,
age int
);
# 插入第一条数据时
insert into xuehu(id,name,age) values (1,'yexueling',18);
select * from xuehu;
# 插入第二条数据时,由于唯一键冲突,插入数据失败,但是主键自增值+1
insert into xuehu(id,name,age) values (null,'yexueling',18);
select * from xuehu;
# 插入第三条数据时,id=3,出现了自增主键不连续的情况。
insert into xuehu(id,name,age) values (null,'hanyan',25);
select * from xuehu;
|