有主键

如果你的表有主键,并且把主键设置为自增。

在 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 用完了会咋样?相关推荐

  1. 面试官问:数据库 delete 表数据,磁盘空间还是被一直占用,为什么?

    以下文章来源方志朋的博客,回复"666"获面试宝典 最近有个上位机获取下位机上报数据的项目,由于上报频率比较频繁且数据量大,导致数据增长过快,磁盘占用多. 为了节约成本,定期进行数 ...

  2. mysql id会用完吗_数据库自增ID用完了会怎样?

    起步 对DBA来说这应该是送分题吧.而我是突如其来的想法想测试下的.正常来说程序员是不会关心自增ID用完的情况的. 以 Mysql 为例,它支持的最大的整型是 unsigned bigint,上限是 ...

  3. 修改自增主键初始化_数据库自增ID用完了会怎么样?

    看到这个问题,我想起当初玩魔兽世界的时候,25H难度的脑残吼的血量已经超过了21亿,所以那时候副本的BOSS都设计成了转阶段.回血的模式,因为魔兽的血量是int型,不能超过2^32大小. 估计暴雪的设 ...

  4. 从面试官问“为什么选择mysql数据库”说开去

    前几天面试,面试官问我:"为什么选择mysql数据库".现在想想,有如下的问题需要解决 关系型数据库有什么特点及举例 非关系型数据库有什么特点及举例 关系型数据库与非关系型数据库有 ...

  5. 面试官问:select......for update会锁表还是锁行?

    欢迎关注方志朋的博客,回复"666"获面试宝典 select查询语句是不会加锁的,但是select .......for update除了有查询的作用外,还会加锁呢,而且它是悲观锁 ...

  6. 面试官问:Kafka 会不会丢消息?怎么处理的?

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! Kafka存在丢消息的问题,消息丢失会发生在Broker, ...

  7. 面试官问:Integer 如何实现节约内存和提升性能的?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:Byte_Liu 来源:https://urlify.cn/ ...

  8. 面试官问我:一个 TCP 连接可以发多少个 HTTP 请求?我竟然回答不上来...

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 作者 | 松若章 来源 | https://zhuanlan.zhihu.com/p/6142 ...

  9. 【Java8新特性】面试官问我:Java8中创建Stream流有哪几种方式?

    写在前面 先说点题外话:不少读者工作几年后,仍然在使用Java7之前版本的方法,对于Java8版本的新特性,甚至是Java7的新特性几乎没有接触过.真心想对这些读者说:你真的需要了解下Java8甚至以 ...

最新文章

  1. 使用 ThinkJS + Vue.js 开发博客系统
  2. Linux 操作系统原理 — 系统结构
  3. 去掉一个linux的ip,linux – iptables删除除一个IP之外的所有传入ICMP请求
  4. 微型计算机的外存储器可与 直接打交道,微型计算机的外存储器可与( )直接打交道。...
  5. java邮件中添加excel_使用java api 创建excel内容并发送邮件
  6. android mdpi对应哪一个屏幕,android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配...
  7. 行内元素和块级元素的区别,为何img、input等行内元素可以设置宽高??(夯实基础)
  8. java控制台代码_Java控制台常用命令
  9. 推荐LaTeX在线编辑器
  10. [转载] python字典类方法
  11. Ansible文件内容修改lineinfile模块(学习笔记五)
  12. 如何扩展/删除swap分区
  13. JAVA常用框架及漏洞
  14. EXcel 数学函数
  15. 解决excel里面“取消隐藏”是灰色的问题
  16. 一个屌丝程序员的青春(二一一)
  17. python 豆瓣源_使用豆瓣源来安装python中的第三方库方法
  18. web安全实验:Attack1-6
  19. 华大(小华)HC32L130工程创建
  20. linux中ping命令详解,全面解析Ping命令

热门文章

  1. R语言使用psych包的fa函数对指定数据集进行因子分析(输入数据为相关性矩阵)、使用rotate参数指定进行斜交旋转提取因子、使用factor.plot函数可视化斜交旋转因子分析、并解读可视化图形
  2. Daydream a Little+偶尔做一下白日梦
  3. Keras图像分割实战:数据整理分割、自定义数据生成器、模型训练
  4. 误差、方差、偏差、噪声、训练误差+验证误差、偏差方差窘境、错误率和误差、过拟合与欠拟合
  5. seaborn+画图+EDA
  6. Stringtie进行转录本组装和定量
  7. 新版IntelliJ IDEA Web项目配置完整流程
  8. 试编写一个汇编语言程序,大写---小写 要求对键盘输入的大写字母用小写字母显示出来。
  9. resumable oracle,Oracle的Resumable特性
  10. c语言实现定长顺序存储,c语言:定长顺序串的基本操作实实现