面试官:数据库自增 ID 用完了会咋样?

01 前言哈喽 , 好久没更新啦 。因为最近在面试 。用了两周时间准备 , 在 3 天之内拿了 5 个 offer , 最后选择了广州某互联网行业独角兽 offer , 昨天刚入职 。这几天刚好整理下在面试中被问到有意思的问题 , 也借此机会跟大家分享下 。
这家企业的面试官有点意思 , 一面是个同龄小哥 , 一起聊了两个小时(聊到我嘴都干了) 。他问了我一个有意(keng)思(b)问题:

数据库中的自增 ID 用完了该怎么办?
这个问题其实可以分为有主键 & 无主键两种情况回答 。
国际惯例 , 先上张脑图:
面试官:数据库自增 ID 用完了会咋样?

文章插图
 
1.1 往期精彩MySQL 查询语句是怎么执行的?
MySQL 索引
MySQL 日志
MySQL 事务与 MVCC
MySQL 的锁机制
MySQL 字符串怎么设计索引?
02 有主键如果你的表有主键 , 并且把主键设置为自增 。
在 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 的值 , 如下图所示:
面试官:数据库自增 ID 用完了会咋样?

文章插图
 
如果此时继续下面的插入语句:
INSERT INTO t (url) VALUES ('wwww.JAVAfish.top/article/erwt/spring')结果就会造成主键冲突:
面试官:数据库自增 ID 用完了会咋样?

文章插图
 
2.1 解决方案虽说 int 4 个字节 , 最大数据量能存储 21 亿 。你可能会觉得这么大的容量 , 应该不至于用完 。但是互联网时代 , 每天都产生大量的数据 , 这是很有可能达到的 。
所以 , 我们的解决方案是:把主键类型改为 bigint , 也就是 8 个字节 。这样能存储的最大数据量就是 2^64-1 , 我也数不清有多少了 。反正在你有生之年应该是够用的 。
PS:单表 21 亿的数据量显然不现实 , 一般来说数据量达到 500 万就该分表了 。
03 没主键另一种情况就是建表时没设置主键 。这种情况 , 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出现下图就是没错的:
面试官:数据库自增 ID 用完了会咋样?

文章插图
 
3、插入三条数据:
insert into t(age) values(1);insert into t(age) values(2);insert into t(age) values(3);此时的数据库数据:
面试官:数据库自增 ID 用完了会咋样?

文章插图
 
4、gdb 把 row_id 修改为最大值:281474976710656
sudo gdb -p 16111 -ex 'p dict_sys->row_id=281474976710656' -batch5、再插入三条数据:
insert into t(age) values(4);insert into t(age) values(5);insert into t(age) values(6);此事的数据库数据:
面试官:数据库自增 ID 用完了会咋样?


推荐阅读