李锋镝的博客 - LiFengdi.Com

  • 首页
  • 时间轴
  • 留言
  • 左邻右舍
  • 我的日常
  • 关于我
青衿之志 履践致远
霁月光风 不萦于怀
  1. 首页
  2. 原创
  3. 正文

MySQL 的自增 ID 用完了,怎么办?

2021年3月30日 12083点热度 0人点赞 0条评论

有一个奇怪的问题,假如MySQL 的自增 ID 用完了,怎么办?

这个知识点比较冷门,不过可以自己手动实践下。

首先,创建一个最简单的表,只包含一个自增id,并插入一条数据。

create table t0(id int unsigned auto_increment primary key) ;
insert into t0 values(null);

通过show命令show create table t0;查看表情况

CREATE TABLE t0 ( id int(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

可以发现 AUTO_INCREMENT 已经自动变成2,这离用完还有很远,我们可以算下最大当前声明的自增ID最大是多少,由于这里定义的是intunsigned,所以最大可以达到2的32幂次方 - 1 = 4294967295

这里有个小技巧,可以在创建表的时候,直接声明AUTO_INCREMENT的初始值:

create table t1(id int unsigned auto_increment primary key) auto_increment = 4294967295;
insert into t1 values(null);

同样,通过show命令,查看t1的表结构:

CREATE TABLE t1 ( id int(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)) ENGINE=InnoDB AUTO_INCREMENT=4294967295 DEFAULT CHARSET=utf8

可以发现,AUTO_INCREMENT已经变成4294967295了,当想再尝试插入一条数据时,得到了下面的异常结果:

insert into t1 values(null) Error Code: 1062. Duplicate entry '4294967295' for key 'PRIMARY' 0.00054 sec

说明,当再次插入时,使用的自增ID还是4294967295,报主键冲突的错误。

4294967295,这个数字已经可以应付大部分的场景了,如果你的服务会经常性的插入和删除数据的话,还是存在用完的风险,建议采用bigint unsigned,这个数字就大了。

不过,还存在另一种情况,如果在创建表没有显示申明主键,会怎么办?

如果是这种情况,InnoDB会自动帮你创建一个不可见的、长度为6字节的row_id,而且InnoDB 维护了一个全局的 dictsys.row_id,所以未定义主键的表都共享该row_id,每次插入一条数据,都把全局row_id当成主键id,然后全局row_id加1

该全局row_id在代码实现上使用的是bigint unsigned类型,但实际上只给row_id留了6字节,这种设计就会存在一个问题:如果全局row_id一直涨,一直涨,直到2的48幂次-1时,这个时候再+1,row_id的低48位都为0,结果在插入新一行数据时,拿到的row_id就为0,存在主键冲突的可能性。

所以,为了避免这种隐患,每个表都需要定一个主键。

除非注明,否则均为李锋镝的博客 - LiFengdi.Com原创文章,转载必须以链接形式标明本文链接
本文链接:https://www.lifengdi.com/archives/article/3241
标签: MySQL 数据库
最后更新:2021年3月30日

李锋镝

既然选择了远方,便只顾风雨兼程。

打赏 点赞
< 上一篇
下一篇 >
guest
您的姓名(必填)
您的邮箱(必填)
您的站点
guest
您的姓名(必填)
您的邮箱(必填)
您的站点
0 评论
Inline Feedbacks
查看所有评论
网站统计
  • 文章总数:264 篇
  • 评论总数:421 篇
  • 标签数量:218 个
  • 最后更新:2022年06月28日
  • 建站日期:2016年6月6

男儿何不带吴钩,收取关山五十州。

最新 热点 随机
最新 热点 随机
MybatisCodeHelperPro激活 @Resource 和 @Autowired 的区别 使用RocketMQ时,服务启动过程中,Consumer在服务未启动时消费消息问题处理 祝大家六一儿童节快乐~~~ 网易云什么时候能有杰伦的歌…… jsdelivr的CDN加速好像不行了……
居家办公了~办理居住证困难重重啊!WordPress的自动更新好烦啊醒醒~补个税了居住证签注...十一节后开工头一天,修了个耳机……
几款Java开发者必备常用的工具,准点下班不在话下 Spring中@NotNull、@NotBlank、@NotEmpty的区别 试了下壁挂炉供暖 jstat命令使用(JDK1.8) 简单易做的早餐(持续更新ing) Chrome等浏览器下出现net::ERR_BLOCKED_BY_CLIENT的解决办法
最近评论
张三 发布于 1 个月前(05月20日) 收到,谢谢博主啊
张三 发布于 1 个月前(05月20日) 请问是哪些插件啊,我想用一下试试
zenmexiugai 发布于 1 个月前(05月20日) 改成一样的还是报错,怎么回事呢
张三 发布于 1 个月前(05月19日) 我不会css,作者的前端是怎么写的啊?包括这些评论啊什么的
张三 发布于 1 个月前(05月19日) 很棒的博客 作者加油啊
有情链接
  • 志文工作室
  • 临窗旋墨
  • 旧时繁华
  • 城南旧事
  • 强仔博客
  • 林三随笔
  • 徐艺扬的博客
  • 猫鼬的星球计划
  • 云辰博客
  • 韩小韩博客
  • 知向前端
  • 阿誉的博客
  • 林羽凡
  • 情侣头像
  • 哥斯拉
  • Xym's blog

COPYRIGHT © 2022 lifengdi.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

豫ICP备16004681号-2