8年面试官问到:数据库自增 ID 用完了会咋样?
有主键
如果你的表有主键,并且把主键设置为自增。
在 MySQL 中,一般会把主键设置成 int 型。而 MySQL 中 int 型占用 4 个字节,作为有符号位的话范围就是 [-2^31,2^31-1],也就是[-2147483648,2147483647];无符号位的话最大值就是 2^32-1,也就是 4294967295。
下面以有符号位创建一张表:
CREATE TABLE IF NOT EXISTS `t`(`id` INT(11) NOT NULL AUTO_INCREMENT,`url` VARCHAR(64) NOT NULL,PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
复制代码
插入一个 id 为最大值 2147483647 的值,如下图所示:
如果此时继续下面的插入语句:
INSERT INTO t (url) VALUES ('wwww.javafish.top/article/erwt/spring')
复制代码
结果就会造成主键冲突:
解决方案
虽说 int 4 个字节,最大数据量能存储 21 亿。你可能会觉得这么大的容量,应该不至于用完。但是互联网时代,每天都产生大量的数据,这是很有可能达到的。
所以,我们的解决方案是:把主键类型改为 bigint,也就是 8 个字节。这样能存储的最大数据量就是 2^64-1,我也数不清有多少了。反正在你有生之年应该是够用的。
PS:单表 21 亿的数据量显然不现实,一般来说数据量达到 500 万就该分表了。
没主键
另一种情况就是建表时没设置主键。这种情况,InnoDB 会自动帮你创建一个不可见的、长度为 6 字节的 row_id,默认是无符号的,所以最大长度是 2^48-1。
实际上 InnoDB 维护了一个全局的 dictsys.row_id,所以未定义主键的表都共享该 row_id,并不是单表独享。每次插入一条数据,都把全局 row_id 当成主键 id,然后全局 row_id 加 1。
这种情况的数据库自增 ID 用完会发生什么呢?
1、创建一张无显示设置主键的表 t:
CREATE TABLE IF NOT EXISTS `t`(`age` int(4) NOT NULL
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
复制代码
2、通过 ps -ef|grep mysql
命令获取 mysql 的进程 ID,然后执行命令,通过 gdb 先把 row_id 修改为 1。PS:没有 gdb 的,百度安装下
sudo gdb -p 16111 -ex 'p dict_sys->row_id=1' -batch
复制代码
出现下图就是没错的:
3、插入三条数据:
insert into t(age) values(1);
insert into t(age) values(2);
insert into t(age) values(3);
复制代码
此时的数据库数据:
4、gdb 把 row_id 修改为最大值:281474976710656
sudo gdb -p 16111 -ex 'p dict_sys->row_id=281474976710656' -batch
复制代码
5、再插入三条数据:
insert into t(age) values(4);
insert into t(age) values(5);
insert into t(age) values(6);
复制代码
此事的数据库数据:
分析:
刚开始设置 row_id 为 1,插入三条数据 1、2、3 的 row_id 也理应是 1、2、3;这是没问题的。
接着设置 row_id 为最大值,紧跟着插入三条数据。这时的数据库结果是:4、5、6、3;你会发现 1、2 被覆盖了。
row_id 达到后最大值后插入的值 4、5、6 的 row_id 分别是 0、1、2;由于 row_id 为 1、2 的值已存在,所以后者的值 5、6 会覆盖掉 row_id 为 1、2 的值。
结论:row_id 达到最大值后会从 0 重新开始算;前面插入的数据就会被后插入的数据覆盖,且不会报错。
总结
数据库自增主键用完后分两种情况:
- 有主键,报主键冲突
- 无主键,InnDB 会自动生成一个全局的row_id。它到达最大值后会从 0 开始算,遇到 row_id 一样时,新数据覆盖旧数据。所以,我们还是尽量给表设置主键。
为什么我说这是个有意(keng)思(b)问题?
我的回答除了以上解决方法外,还提到在业务开发中,我们不会等到主键用完那天就已经分库分表了,基本不会遇到这种情况。
这时,面试官可能会问你分库分表咋处理,如果你不会就不要主动提了,点到即止。
参考文章
- blog.csdn.net/weixin_39640090/article/details/113227742
- blog.csdn.net/qq_35393693/article/details/100059966
- time.geekbang.org/column/article/69862
大厂面试题 & 电子书
如果看到这里,喜欢这篇文章的话,请帮点个好看。
初次见面,也不知道送你们啥。干脆就送几百本电子书和2021最新面试资料吧。微信搜索JavaFish回复电子书送你 1000+ 本编程电子书;回复面试送点面试题;回复1024送你一套完整的 java 视频教程。
面试题都是有答案的,详细如下所示:有需要的就来拿吧,绝对免费,无套路获取。
需要相关资料可以扫一扫 备注【java】
8年面试官问到:数据库自增 ID 用完了会咋样?相关推荐
- 面试官问:数据库 delete 表数据,磁盘空间还是被一直占用,为什么?
以下文章来源方志朋的博客,回复"666"获面试宝典 最近有个上位机获取下位机上报数据的项目,由于上报频率比较频繁且数据量大,导致数据增长过快,磁盘占用多. 为了节约成本,定期进行数 ...
- mysql id会用完吗_数据库自增ID用完了会怎样?
起步 对DBA来说这应该是送分题吧.而我是突如其来的想法想测试下的.正常来说程序员是不会关心自增ID用完的情况的. 以 Mysql 为例,它支持的最大的整型是 unsigned bigint,上限是 ...
- 修改自增主键初始化_数据库自增ID用完了会怎么样?
看到这个问题,我想起当初玩魔兽世界的时候,25H难度的脑残吼的血量已经超过了21亿,所以那时候副本的BOSS都设计成了转阶段.回血的模式,因为魔兽的血量是int型,不能超过2^32大小. 估计暴雪的设 ...
- 从面试官问“为什么选择mysql数据库”说开去
前几天面试,面试官问我:"为什么选择mysql数据库".现在想想,有如下的问题需要解决 关系型数据库有什么特点及举例 非关系型数据库有什么特点及举例 关系型数据库与非关系型数据库有 ...
- 面试官问:select......for update会锁表还是锁行?
欢迎关注方志朋的博客,回复"666"获面试宝典 select查询语句是不会加锁的,但是select .......for update除了有查询的作用外,还会加锁呢,而且它是悲观锁 ...
- 面试官问:Kafka 会不会丢消息?怎么处理的?
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! Kafka存在丢消息的问题,消息丢失会发生在Broker, ...
- 面试官问:Integer 如何实现节约内存和提升性能的?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:Byte_Liu 来源:https://urlify.cn/ ...
- 面试官问我:一个 TCP 连接可以发多少个 HTTP 请求?我竟然回答不上来...
点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 作者 | 松若章 来源 | https://zhuanlan.zhihu.com/p/6142 ...
- 【Java8新特性】面试官问我:Java8中创建Stream流有哪几种方式?
写在前面 先说点题外话:不少读者工作几年后,仍然在使用Java7之前版本的方法,对于Java8版本的新特性,甚至是Java7的新特性几乎没有接触过.真心想对这些读者说:你真的需要了解下Java8甚至以 ...
最新文章
- 使用 ThinkJS + Vue.js 开发博客系统
- Linux 操作系统原理 — 系统结构
- 去掉一个linux的ip,linux – iptables删除除一个IP之外的所有传入ICMP请求
- 微型计算机的外存储器可与 直接打交道,微型计算机的外存储器可与( )直接打交道。...
- java邮件中添加excel_使用java api 创建excel内容并发送邮件
- android mdpi对应哪一个屏幕,android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配...
- 行内元素和块级元素的区别,为何img、input等行内元素可以设置宽高??(夯实基础)
- java控制台代码_Java控制台常用命令
- 推荐LaTeX在线编辑器
- [转载] python字典类方法
- Ansible文件内容修改lineinfile模块(学习笔记五)
- 如何扩展/删除swap分区
- JAVA常用框架及漏洞
- EXcel 数学函数
- 解决excel里面“取消隐藏”是灰色的问题
- 一个屌丝程序员的青春(二一一)
- python 豆瓣源_使用豆瓣源来安装python中的第三方库方法
- web安全实验:Attack1-6
- 华大(小华)HC32L130工程创建
- linux中ping命令详解,全面解析Ping命令
热门文章
- R语言使用psych包的fa函数对指定数据集进行因子分析(输入数据为相关性矩阵)、使用rotate参数指定进行斜交旋转提取因子、使用factor.plot函数可视化斜交旋转因子分析、并解读可视化图形
- Daydream a Little+偶尔做一下白日梦
- Keras图像分割实战:数据整理分割、自定义数据生成器、模型训练
- 误差、方差、偏差、噪声、训练误差+验证误差、偏差方差窘境、错误率和误差、过拟合与欠拟合
- seaborn+画图+EDA
- Stringtie进行转录本组装和定量
- 新版IntelliJ IDEA Web项目配置完整流程
- 试编写一个汇编语言程序,大写---小写 要求对键盘输入的大写字母用小写字母显示出来。
- resumable oracle,Oracle的Resumable特性
- c语言实现定长顺序存储,c语言:定长顺序串的基本操作实实现