面试官:数据库自增ID用完了会怎么样?
看到这个问题,我想起当初玩魔兽世界的时候,25H难度的脑残吼的血量已经超过了21亿,所以那时候副本的BOSS都设计成了转阶段、回血的模式,因为魔兽的血量是int型,不能超过2^32大小。
估计暴雪的设计师都没想到几个资料片下来血量都超过int上限了,以至于大家猜想才会有后来的属性压缩。
这些都是题外话,只是告诉你数据量大了是有可能达到上限的而已,回到Mysql自增ID上限的问题,可以分为两个方面来说。
1.有主键
如果设置了主键,并且一般会把主键设置成自增。
我们知道,Mysql里int类型是4个字节,如果有符号位的话就是[-2^31,2^31-1],无符号位的话最大值就是2^32-1,也就是4294967295。
创建一张表试试:
CREATE TABLE `test1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2147483647 DEFAULT CHARSET=utf8mb4;
然后执行插入
insert into test1(name) values('qq');
这样表里就有一条达到有符号位的最大值上限的数据。

如果再次执行插入语句:
insert into test1(name) values('ww');
就会看到错误提示:1062 - Duplicate entry '2147483647' for key 'PRIMARY', Time: 0.000000s。
也就是说,如果设置了主键并且自增的话,达到自增主键上限就会报错重复的主键key。
解决方案,mysql主键改为bigint,也就是8个字节。
设计的时候要考虑清楚值的上限是多少,如果业务频繁插入的话,21亿的数字其实还是有可能达到的。
2.没有主键
如果没有设置主键的话,InnoDB则会自动帮你创建一个6个字节的row_id,由于row_id是无符号的,所以最大长度是2^48-1。
同样创建一张表作为测试:
CREATE TABLE `test2` (
`name` varchar(32) NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
通过ps -ef|grep mysql拿到mysql的进程ID,然后执行命令,通过gdb先把row_id修改为1
sudo gdb -p 2584 -ex 'p dict_sys->row_id=1' -batch
然后插入几条数据:
insert into test2(name) values('1');
insert into test2(name) values('2');
insert into test2(name) values('3');
再次修改row_id为2^48,也就是281474976710656
sudo gdb -p 2584 -ex 'p dict_sys->row_id=281474976710656' -batch
再次插入数据
insert into test2(name) values('4');
insert into test2(name) values('5');
insert into test2(name) values('6');
然后查询数据会发现3条数据是4,5,6,3。
因为我们先设置row_id=1开始,所以1,2,3的row_id也是1,2,3。
修改row_id为上限值之后,row_id会从0重新开始计算,所以4,5,6的row_id就是0,1,2。
由于1,2数据已经存在,数据则是会被覆盖。
总结
自增ID达到上限用完了之后,分为两种情况:
- 如果设置了主键,那么将会报错主键冲突。
- 如果没有设置主键,数据库则会帮我们自动生成一个全局的row_id,新数据会覆盖老数据
解决方案:
表尽可能都要设置主键,主键尽量使用bigint类型,21亿的上限还是有可能达到的,比如魔兽,虽然说row_id上限高达281万亿,但是覆盖数据显然是不可接受的。
- END -
面试官:数据库自增ID用完了会怎么样?的更多相关文章
- 分库分表数据库自增 id
分库分表之后,ID 主键如何处理? 面试题 分库分表之后,id 主键如何处理? 面试官心理分析 其实这是分库分表之后你必然要面对的一个问题,就是 id 咋生成?因为要是分成多个表之后,每个表都是从 1 ...
- mysql 数据库自增id 的总结
有一个表StuInfo,里面只有两列 StuID,StuName其中StuID是int型,主键,自增列.现在我要插入数据,让他自动的向上增长,insert into StuInfo(StuID,Stu ...
- 解决数据库自增ID的问题
(1)设置主键自增为何不可取这样的话,数据库本身是单点,不可拆库,因为id会重复. (2)依赖数据库自增机制达到全局ID唯一使用如下语句:REPLACE INTO Tickets64 (stub) V ...
- 分布式ID系列(3)——数据库自增ID机制适合做分布式ID吗
数据库自增ID机制原理介绍 在分布式里面,数据库的自增ID机制的主要原理是:数据库自增ID和mysql数据库的replace_into()函数实现的.这里的replace数据库自增ID和mysql数据 ...
- mysql数据库表自增ID批量清零 AUTO_INCREMENT = 0
mysql数据库表自增ID批量清零 AUTO_INCREMENT = 0 #将数据库表自增ID批量清零 SELECT CONCAT( 'ALTER TABLE ', TABLE_NAME, ' AUT ...
- mybatis获取数据库自增id
http://blog.csdn.net/dyllove98/article/details/8866357 http://www.iteye.com/problems/86864 insert标签中 ...
- MySQL 的自增 ID 用完了,怎么办?
一.简述 在 MySQL 中用很多类型的自增 ID,每个自增 ID 都设置了初始值.一般情况下初始值都是从 0 开始,然后按照一定的步长增加.在 MySQL 中只要定义了这个数的字节长度,那么就会 ...
- mysql数据库自增id重新从1排序的两种方法
mysql默认自增ID是从1开始了,但当我们如果有插入表或使用delete删除id之后ID就会不会从1开始了哦. 使用mysql时,通常表中会有一个自增的id字段,但当我们想将表中的数据清空重新添 ...
- MySQL的自增ID用完了,怎么办?
既然这块知识点不清楚,那回头就自己动手实践下. 首先,创建一个最简单的表,只包含一个自增id,并插入一条数据. create table t0(id int unsigned auto_increme ...
随机推荐
- idea:如果String 跟System该怎么解决
这个问题还是比较简单的,但有很多小白不知道,我也是刚刚才遇到查了一些资料才知道的 接下来这里就是需要配置你的SDK,所以请你点击右上角的图标,进行配置SDK jdk下载地址:https://www.o ...
- RocketMq(三):server端处理框架及消费数据查找实现
rocketmq作为一个高性能的消息中间件,咱们光停留在使用层面,总感觉缺点什么.虽然rocketmq的官方设计文档讲得还是比较详细的,但纸上得来终觉浅!今天我们就来亲自挖一挖rocketmq的实现细 ...
- 从go-libp2p开始
这里是从一系列关于libp2p的go实现教程开始,go-libp2p 我们会讲述go的安装,go模块的设置,启动libp2p节点,并在它们之间发送消息. 安装go go-libp2p推荐使用包含 mo ...
- MySQL入门看这一篇就够了
MySQL JavaEE:企业级Java开发 web阶段 分为1.前端(页面,展示数据库中的数据) 2.后台(连接点:链接数据库JDBC.Mybatis,链接前端(控制视图跳转,给前端传递数据)) 3 ...
- 自己编写k8s
## 基于Docker和Kubernetes的企业级DevOps实践训练营 ### 课程准备 1. 离线镜像包 百度:https://pan.baidu.com/s/1N1AYGCYftYGn6L0Q ...
- React中对render进行的小优化
react中state和props变化会造成render的重新渲染,有时候我们会在render函数中进行一些稍微复杂的逻辑运算 比如说,像下边这种 在props中将 industries引入,然后对其 ...
- Python分析世界幸福指数
前言 民意测验机构盖洛普从2012年起,每年都会在联合国计划下发布<世界幸福指数报告>,报告会综合两年内150多个国家的国民对其所处社会.城市和自然环境等因素进行评价后,再根据他们所感知的 ...
- 浅谈JAVA代码优化
JAVA代码的优化分为两个方面: 一.减小代码的体积.二.提高代码的执行效率. ============================================================ ...
- Peomise
什么是promise 简单回答: 一种异步的解决方案 回顾一下什么是异步 事件 / setTimeout 异步执行的时机 同步->异步微任务->GUI渲染->异步宏任务 #为 ...
- 旁站和C段的简要解释
旁注与C段嗅探的意义,旁注的意思就是从同台服务器上的其他网站入手,提权,然后把服务器端了,就自然把那个网站端了.C段嗅探,每个IP有ABCD四个段,举个例子,192.168.0.1,A段就是192,B ...