字节面试:MySQL自增ID用完会怎样?
在一些中小型项目开发中,我们通常会使用自增 ID 来作为主键的生成策略,但随着时间的推移,数据库的信息也会越来越多,尤其是使用自增 ID 作为日志表的主键生成策略时,可能很快就会遇到 ID 被用完的情况,那么如果发生了这种情况,MySQL 又会怎样执行呢?
PS:当然,在分库分表的场景中,我们通常会使用雪花算法来替代自增 ID,但中小型项目开发中,使用自增 ID 的场景还是比较多的。
1.自增ID
在 MySQL 中,如果字段的数据类型为整数类型(如 INT、BIGINT 等),则可以通过关键字“AUTO_INCREMENT”来设置让当前的字段实现自增,例如以下 SQL:
CREATE TABLE example_table (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(128)
);
1.1 优点分析
自增 ID 的优点如下:
- 简单方便,能自动为每行数据分配唯一的标识。
- 对于按顺序插入的数据,能很好地反映数据插入的先后顺序。
1.2 缺点分析
自增 ID 的缺点如下:
- 在数据进行迁移或分库分表时,可能会出现问题,需要特殊处理。
- 如果数据量非常大,可能会达到自增 ID 的上限。
- 存在安全性问题,比如通过自增 ID 可能会推测出一些业务信息。例如,一个电商订单表使用自增 ID 作为主键,可能会被竞争对手通过订单号大致推测出业务量等信息。
2.自增ID用完会怎样?
自增 ID 分为以下两种情况:
一种是主键自增 ID 用完后的情况,另一种是 InnoDB 引擎中未设置主键时使用 row_id 用完后的场景,它们的情况是不一样的,所以我们分开来聊。
2.1 主键自增ID用完
当主键自增 ID 达到上限后,再新增下一条数据时,它的 ID 不会变(还是最大的值),只是此时再添加数据时,因为主键约束的原因,ID 是不允许重复的,所以就会报错提示主键冲突。
我们可以使用以下 SQL 来测试:
CREATE TABLE t (
id INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(128)
) auto_increment=2147483647;
insert into t(id,`name`) values(null,'javacn.site');
select * from t;
insert into t(id,`name`) values(null,'www.javacn.site');
以上 SQL 是创建了一个表 t,并且给 t 表的主键 id 设置自增 ID,之后再将表的自增 ID 初始化为 INT(有符号)的最大值 2147483647,然后再添加两条数据。
以上 SQL 的执行结果如下:
从上面的执行结果可以看出:当主键自增 ID 达到上限后,再新增下一条数据时,它的 ID 不会变(还是最大的值),只是此时再添加数据时,因为主键约束的原因,ID 是不允许重复的,所以就会报错提示主键冲突。
2.2 row_id用完
如果表没有设置主键,InnoDB 会自动创建一个全局隐藏的 row_id,其长度为 6 个字节,当 row_id 达到上限后,它的执行流程和主键 ID 不同,它是再次归零,然后重新递增,如果出现相同的 row_id,后面的数据会覆盖之前的数据。
课后思考
如何验证 row_id 用完后归零覆盖原数据的情况?
本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。
字节面试:MySQL自增ID用完会怎样?的更多相关文章
- 45 MySQL自增id
45 MySQL自增id 表定义自增id 说到自增id,前面提到mysql的自增id不连续,当表定义的自增值达到上限后的逻辑是:再申请下一个id时,得到的值保持不变 ; insert into t v ...
- MySQL自增ID 起始值 修改方法
在mysql中很多朋友都认为字段为AUTO_INCREMENT类型自增ID值是无法修改,其实这样理解是错误的,下面介绍mysql自增ID的起始值修改与设置方法. 通常的设置自增字段的方法: 创建表格时 ...
- Mysql自增ID起始值修改
在mysql中很多朋友都认为字段为AUTO_INCREMENT类型自增ID值是无法修改,其实这样理解是错误的,下面介绍mysql自增ID的起始值修改与设置方法.通常的设置自增字段的方法:创建表格时添加 ...
- mysql自增id归0
mysql自增id归0 ALTER TABLE table_name AUTO_INCREMENT=1;
- 45 | 自增id用完怎么办?
MySQL 里有很多自增的 id,每个自增 id 都是定义了初始值,然后不停地往上加步长.虽然自然数是没有上限的,但是在计算机里,只要定义了表示这个数的字节长度,那它就有上限.比如,无符号整型 (un ...
- mysql自增id超大问题查询
引言 小A正在balabala写代码呢,DBA小B突然发来了一条消息,"快看看你的用户特定信息表T,里面的主键,也就是自增id,都到16亿了,这才多久,在这样下去过不了多久主键就要超出范围了 ...
- 据库自增ID用完
Mysql里int类型是4个字节,如果有符号位的话就是[-2^31,2^31-1],无符号位的话最大值就是2^32-1,也就是4294967295. 自增ID达到上限用完了之后,分为两种情况: 如果设 ...
- 基于MySQL自增ID字段增量扫描研究
目录 目录 1 1. 问题 1 2. 背景 1 3. InnoDB表 2 3.1. 自增ID为主键 2 3.2. 自增ID为普通索引 4 3.3. 原因分析 7 4. MyISAM表 8 4.1. 自 ...
- 万答#13,MySQL自增键用完后,插入数据会发生什么情况
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 MySQL自增键用完了,插入数据会发生什么情况 1.实验场景 GreatSQL ...
- mysql 自增id
在开发的时候遇到了 自增id变成2147483647 莫名其妙 然后发现是自己没把自增id改为 无符号的原因 把无符号勾上就ok了
随机推荐
- 全面提升易用性:OpenClusterManagement 0.7 版本发布
简介:千呼万唤始出来,三月末 OpenClusterManagement 社区正式发布了 v0.7 版本.在新的版本有一系列新的功能特性欢迎感兴趣的读者体验探索,同时在这个版本中社区维护者对目前已有 ...
- Timing:在线自习室快速搭建
通过超低延迟的音视频通信技术.视频连麦.弱网传输算法,快速搭建自习场景,提升自习效率. 客户简介 氪细胞主打产品Timing,是国内最早推出,也是规模最大的在线自习室,是新一代的教育与社交融合平 ...
- 10种编程语言实现Y组合子
简介: Y组合子是Lambda演算的一部分,也是函数式编程的理论基础.它是一种方法/技巧,在没有赋值语句的前提下定义递归的匿名函数,即仅仅通过Lambda表达式这个最基本的"原子" ...
- 全球首款乘云而来的存储产品CDS诞生!
9月22日,阿里云发布全球首款"云定义存储"(Cloud Defined Storage,CDS)产品.作为一款本地部署的分布式存储产品,阿里云CDS拥有与公共云存储相同的技术架 ...
- [FAQ] MySQL Workbench 设置界面字体大小
MySQL Workbench 连接数据库后,点击右上角的图标,进入 Fonts & Colors 设置. 示例: Tool:SQL美化工具 Ref:MySQLWorkbench Link ...
- WinDbg 加载 dotnet core 的 sos.dll 辅助调试方法
本文告诉大家如何加载 .NET Core 或 .NET 5 的 sos.dll 文件到 WinDbg 的方法 和 .NET Framework 或 dotnet core 2.0 不相同的是,当前的 ...
- MDK在头文件中使用预编译器时,#ifdef 无效的问题
问题:在头文件中使用预编译时,会出现无效的现象 在a.h文件中定义了宏AA_TEST,如下所示 #ifndef __A_H #define __A_H #define AA_TEST #endif 在 ...
- Caused by: java.lang.ClassNotFoundException: org.apache.http.message.TokenParser
写完程序启动不报错,执行时总是报错 java.lang.ClassNotFoundException: org.apache.http.message.TokenParser 认真检查代码没问题,试了 ...
- easyExcel多行表头设定不同样式和特定单元格设定样式的实现
前言 有个需求,需要设置Excel导出的样式,样式如下图所示,有三个表头行,第一个表头行需要加粗和灰色背景,另外两个表头行使用另外的样式,并且当测试结果单元格出现x或者未通过的时候,设置其为红色字体. ...
- typescript基础知识汇总
JavaScript中所有事物(字符串.数值.数组.函数)都是对象,都有属性和方法.1.用函数定义对象,然后new对象实例.2.用Object定义并创建对象实例var o = new Object(t ...