面试官:MySQL的自增 ID 用完了,怎么办?

如果你用过或了解过MySQL,那你一定知道自增主键了。每个自增id都是定义了初始值,然后按照指定步长增长(默认步长是1)。虽然,自然数是没有上限的,但是我们在设计表结构的时候,通常都会指定字段长度,那么,这时候id就有上限了。

既然有上限,就总有被用完的时候,如果id用完了,怎么办呢?今天就一起来学习下吧。

自增id

说到自增id,相信你的第一反应一定是在设计表结构的时候自定义一个自增id字段,那么就有一个问题啦,在插入数据时有可能唯一主键冲、sql事务回滚、批量插入的时候,批量申请自增值等原因导致自增id是不连续的。

表定义的自增值达到上线后的逻辑是:再申请下一个id的时候,获取的是同一个值(最大值)。大家可以插入sql设置id是最大值,再insert一条不主动设置id的语句就可以验证这一结论啦。这个时候如果再插入就是报主键冲突咯~

这里提醒一下:232-1(4294967295)不是一个特别大的数,对于一个频繁插入删除数据的表来说,是可能会被用完的。因此在建表的时候你需要考察你的表是否有可能达到这个上限,如果有可能,就应该创建成 8 个字节的 bigint unsigned。

InnoDB系统自增row_id

如果你创建的 InnoDB 表没有指定主键,那么 InnoDB 会给你创建一个不可见的,长度为 6 个字节的 row_id。InnoDB 维护了一个全局的 dict_sys.row_id 值,所有无主键的 InnoDB 表,每插入一行数据,都将当前的 dict_sys.row_id 值作为要插入数据的 row_id,然后把 dict_sys.row_id 的值加 1。

图片

实际上,在代码实现时 row_id 是一个长度为8字节的无符号长整型 (bigint unsigned)。但是,InnoDB 在设计时,给 row_id 留的只是 6 个字节的长度,这样写到数据表中时只放了最后 6 个字节,所以 row_id 能写到数据表中的值,就有两个特征:

row_id 写入表中的值范围,是从 0 到 248-1;

当 dict_sys.row_id=2^48时,如果再有插入数据的行为要来申请 row_id,拿到以后再取最后 6 个字节的话就是 0。

虽然,2^48这个数字已经很大了,但是大家要知道 一个系统是可以跑很久的,那么还是可能达到上限的,这时候再申请就会覆盖原来的记录了。因此,尽量不要选择这种方式!

Xid

MySQL中redo log 和 binlog 相配合的时候,它们有一个共同的字段叫作 Xid。它在 MySQL 中是用来对应事务的。

MySQL 内部维护了一个全局变量 global_query_id,每次执行语句的时候将它赋值给 Query_id,然后给这个变量加 1。如果当前语句是这个事务执行的第一条语句,那么 MySQL 还会同时把 Query_id 赋值给这个事务的 Xid。而 global_query_id 是一个纯内存变量,重启之后就清零了。所以在同一个数据库实例中,不同事务的 Xid 也是有可能相同的。

Innodb trx_id

InnoDB 内部维护了一个 max_trx_id 全局变量,每次需要申请一个新的 trx_id 时,就获得 max_trx_id 的当前值,然后并将 max_trx_id 加 1。

InnoDB 数据可见性的核心思想是:每一行数据都记录了更新它的 trx_id,当一个事务读到一行数据的时候,判断这个数据是否可见的方法,就是通过事务的一致性视图与这行数据的 trx_id 做对比。但是这个过程有脏读存在,那么这个id就不会是原子性的,存在重复的可能性。

thread_id

其实,线程 id 才是 MySQL 中最常见的一种自增 id。平时我们在查各种现场的时候,show processlist 里面的第一列,就是 thread_id。

thread_id 的逻辑很好理解:系统保存了一个全局变量 thread_id_counter,每新建一个连接,就将 thread_id_counter 赋值给这个新连接的线程变量。

thread_id_counter 定义的大小是 4 个字节,因此达到 232-1 后,它就会重置为 0,然后继续增加。结果跟row_id一样,就会覆盖原有记录了。

上面介绍了几种MySQL自身的一些自增id,其实,实际运用中,我们也可能会选择外部的自增主键,然后持久化到数据库,以此来代替数据库自身的自增id。下面来说说吧。

Redis自增主键

其实外部自增主键的生成方式有很多,为什么我要介绍redis呢?因为我自己在实际应用中使用发现它的很多优点。

redis自身是原子性的,因此高并发也是线程安全的。假设主键字段长度20,我们以时间+自增数来构成主键,例如:8位日期+12自增数。那么,根据业务性质可以决定时间取年月日或者到毫秒级,那么在毫秒之间自增数的重复概率是极小极小的,基本的业务都能适用。

总结

上面介绍了好几种自增id,每种自增 id 有各自的应用场景,在达到上限后的表现也不同:

1、 表的自增 id 达到上限后,再申请时它的值就不会改变,进而导致继续插入数据时报主键冲突的错误


2、 row_id 达到上限后,则会归 0 再重新递增,如果出现相同的 row_id,后写的数据会覆盖之前的数据


3、 Xid 只需要不在同一个 binlog 文件中出现重复值即可。虽然理论上会出现重复值,但是概率极小,可以忽略不计


4、 InnoDB 的 max_trx_id 递增值每次 MySQL 重启都会被保存起来,所以我们文章中提到的脏读的例子就是一个必现的 bug,好在留给我们的时间还很充裕


5、 thread_id 是我们使用中最常见的,而且也是处理得最好的一个自增 id 逻辑了


6、 redis外部自增,毫秒级别,理论上会出现重复值,但是概率极小,可以忽略不计


7、 其实,每种自增id都有各自的适用场景,大家在平时使用中可以根据具体场景再选择。但是要未雨绸缪,因为系统的运行时间和数据的存储,这些都是要考虑在内的,综合考虑,选择一个在系统运行期间一定不会出现重复即刻。你学会了吗?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/545148.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flink入门学习 | 大数据技术

⭐简单说两句⭐ ✨ 正在努力的小新~ 💖 超级爱分享,分享各种有趣干货! 👩‍💻 提供:模拟面试 | 简历诊断 | 独家简历模板 🌈 感谢关注,关注了你就是我的超级粉丝啦! &…

优化汽车制造中的库存管理

在拥有足够的库存以满足客户需求和最大限度地减少过剩库存之间取得适当的平衡,对于高效运营和正向现金流运营至关重要。我们将探讨如何利用数据见解和预测技术来支持汽车制造商进行精益运营,避免库存过多或不足的缺陷。 销售模式告诉我们什么&#xff1…

手拉手安装启动Kafka2.13

启动Kafka本地环境需Java 8以上 Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 Kafka启动…

创新营销利器:淘宝扭蛋机小程序开发全解析

在数字化浪潮的推动下,淘宝扭蛋机小程序的开发成为了一种全新的购物体验。它巧妙地将传统扭蛋机的乐趣与移动技术的便捷相结合,为用户带来了前所未有的惊喜与互动。 淘宝扭蛋机小程序的开发,不仅是一次技术的革新,更是一次购物方…

c++中常用库函数

大小写转换 islower/isupper函数 char ch1 A; char ch2 b;//使用islower函数判断字符是否为小写字母 if(islower(ch1)){cout << ch1 << "is a lowercase letter." << end1; } else{cout << ch1 << "is not a lowercase lette…

Java单例集合

Collection接口介绍 Collection 表示一组对象&#xff0c;它是集中、收集的意思。Collection接口的两个子接口是List、Set接口。 Collection接口中定义的方法 方法说明boolean add(Object element)增加元素到容器中boolean remove(Object element)从容器中移除元素 boolean c…

【源码】2024全开源多语言多商户跨境商城源码|多语言跨境外贸电商系统App

ikTok SHOP跨境电商系统V8版是一套B2CB2B跨境电商商城系统源码&#xff0c;多商户多语言&#xff0c;全新百变DIY模板&#xff1b;该系统支持B-C自营、B-B-C第三方卖家系统、B2B批发电商模式&#xff1b;该源码是使用Laravel框架PHP开发的&#xff0c;前后端全开源可二开。 版…

行业模板|DataEase批发零售大屏模板推荐

DataEase开源数据可视化分析平台于2022年6月发布模板市场&#xff08;https://templates-de.fit2cloud.com&#xff09;&#xff0c;并于2024年1月新增适用于DataEase v2版本的模板分类。模板市场旨在为DataEase用户提供专业、美观、拿来即用的大屏模板&#xff0c;方便用户根据…

构建跨设备3D应用:HOOPS的跨平台开发能力

在当今数字化和可视化需求不断提升的时代&#xff0c;三维技术的应用越来越广泛&#xff0c;尤其在制造、建筑、工程及媒体行业。HOOPS&#xff0c;由Tech Soft 3D开发&#xff0c;是一套全面的软件开发工具包&#xff0c;用于构建高性能的三维应用程序。该工具包涵盖了从三维渲…

韩国ECS电子离心开关的安装和应用

韩国ECS电子式离心开关是一种新型的固体开关&#xff0c;其工作原理是通过采样电动机的电流、电压、相位等参数来判定电动机的启动转速。当电动机转速达到额定转速的72%~83%时&#xff0c;启动电容将被断开&#xff0c;使电动机启动运转。这种开关具有工作精确、可靠性高、一致…

【新特性】专为开发者设计的 Jira 个性化工作建议

开发者体验&#xff08;Developer Experience&#xff0c;简称 DX&#xff09;是指开发人员在使用工具、框架或平台时所体验到的整体感受和印象。类似于用户体验&#xff08;User Experience&#xff0c;简称UX&#xff09;&#xff0c;开发者体验关注的是开发者在他们的工作中…

DrugBAN:基于双线性注意力网络进行药物-靶点结合预测。

DrugBan&#xff1a;一种可解释的双线性注意力网络进行药物-靶点结合预测。 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 DrugBan&#xff1a;一种可解释的双线性注意力网络进行药物-靶点结合预测。前言一、模型…

gcn代码处理出现的问题

README 版本不一致 python 2.7 PYTHON 3.7 切换 TensorFlow系统的学习使用 数据集下载

yolo系列(之一)

深度学习经典检测算法 two-stage (两阶段) : Faster-rcnn Mask-Rcnn系列 &#xff08;输入图像---》CNN特征---》预选框---》输出结果&#xff09; one-stage (单阶段): YOLO系列 &#xff08;输入图像---》CNN特征---》输出结果&#xff09; one-stage的特点&#xff1a;&…

无人机GB42590接收端 +接收端,同时支持2.4G与5.8G双频WIFI模组

严格按照GB42590的协议开发的发射端&#xff0c;通过串口和模块通讯&#xff0c;默认波特率 921600。 http://www.doit.am/首页-深圳四博智联科技有限公司-淘宝网https://shop144145132.taobao.com/?spma230r.7195193.1997079397.2.71f6771dJHT2r0 二、接口文档 单片机和模…

Netron 显示每层输入shape

前言 我是用yolov5s直接export的onnx&#xff0c;用netron打卡&#xff0c;发现看不到每层的输入&#xff0c;又不想自己算。 步骤 1.准备好onnx 2 执行以下代码 import onnx onnx_ori"yolov5s.onnx" onnx_show"yolov5s_show.onnx" onnx_graph onnx.l…

MGRE-OSPF接口网络类型实验

OSPF接口网络类型实验 一&#xff0c;实验拓扑 初始拓扑&#xff1a; 最终拓扑&#xff1a; 二&#xff0c;实验要求及分析 要求&#xff1a; 1&#xff0c;R6为ISP只能配置IP地址&#xff0c;R1-R5的环回为私有网段 2&#xff0c;R1/R4/R5为全连的MGRE结构&#xff0c;R…

sd sdxl diffusers GPU 显存 优化

# 使用 fp 16, 显存减少&#xff0c;速度提示 pipe StableDiffusionXLPipeline.from_single_file(modelPath,dtypetorch.bfloat16, variant"fp16", use_safetensorsTrue, load_safety_checkerFalse,device_map"auto")# VAE并发解码&#xff0c;改为串行&a…

九州金榜|孩子青春期应该如何家庭教育?

青春期&#xff0c;是一个人从儿童走向成年的重要过渡阶段&#xff0c;也是心理、生理发生巨大变化的时期。面对这一特殊时期的孩子&#xff0c;家庭教育显得尤为重要。那么&#xff0c;作为家长&#xff0c;我们该如何进行青春期孩子的家庭教育呢&#xff1f;九州金榜家庭教育…

基于springboot酒店管理系统的人事部门管理子系统

基于springboot酒店管理系统的人事部门管理子系统 前言 酒店管理系统的设计与实现-人事部门管理子系统&#xff0c;可以让用户在最短的时间里享受到最好的服务&#xff1b;而开发本系统&#xff0c;又能够提高系统整体工作水平&#xff0c;简化工作程序&#xff0c;这对管理员…