跟同事杠上了,用雪花算法生成的id做主键对MySQL性能有影响?

news2024/10/7 14:23:39

公司最近开发了一个新项目,设计表时由于有些字段需要对外展示,所以使用了雪花算法生成的id做主键。

不过有位同事对此提出了异议,认为雪花算法生成的id不是顺序递增的,会对MySQL的性能造成影响。

经过交流,发现持有这种认知的还有好几位同事,估摸着对此有疑问的朋友也不少,所以今天我们来分析一下,用雪花算法生成的id做主键,对MySQL性能到底有没有影响?MySQL必须使用连续递增的主键才能发挥最大性能?

既然要分析不同主键的性能,那么就得先了解一下MySQL的数据是如何存储的。

相信只要稍微了解过MySQL的朋友估计都知道,MySQL的InnoDB引擎采用B+树来存储数据,为了数据的安全性,这些数据最终会持久化到磁盘上。

那么我们在查询或者修改数据时,如果每次都把数据全部从磁盘加载到内存好像不太现实,每次只读一条数据又太浪费IO,那怎么办呢?

于是设计MySQL的这些大神们提出了页的概念,即将数据保存到很多个页上面,内存和磁盘交互时以页为单位。

默认情况下,一个页的大小是16KB,也就是说,每次从磁盘会最少加载16KB的数据到内存里。反过来,每次最少把16KB的数据从内存中持久化到磁盘。

这样,时间和空间都利用到了,最大化的保证了性能。

当然,页的种类也有很多,比如保存表空间信息的页,undo日志页,存放数据的数据页等,本文中我们只讨论数据页和目录页。

下图就是一个InnoDB数据页的结构,大家心里有一个印象即可。

User Records就是用来真正保存我们的数据的,我们看一下数据是如何在页中保存的。

需要特别注意的是,为了性能,这些记录是按照主键的大小按从小到大顺序排放的,最终组成一个单向链表。另外每个数据页都会生成一个页目录,通过主键查找某一条记录时通过二分查找法即可快速找到需要的数据。

上面我们提过,一个页默认只有16KB,也就是说存储的数据是有限的,所以当要存储很多数据时,就需要申请很多数据页,如下所示:

从上图中我们可以看到,每个数据页都保存了很多条记录,相邻页之间还通过双向链表保存着联系。

需要注意的是,这些数据页在物理空间上不一定是连续的地址。

到这里我们知道了MySQL通过数据页来存储数据,但是随着表数据的增多,会带来一个很明显的问题:页太多了不好管理。

所以InnoDB的大神们又设计了目录页(目录页+数据页就组成了一颗索引树)。

看名字也知道,目录页只是一个目录,不会存储具体的数据。

它保存的数据其实特别简单:主键和页号。

从上图中我们可以看到,页30是一个目录页(可以把他当做树的根节点),页10、页28、页9、页20是真正存放数据的数据页。

在目录页中,会存放每一个数据页的最小主键id以及对应的页号,并且按照主键id排序。

在数据页中,数据也是按照主键从小到大排序的,并且后一个页的最小记录会比上一个页的最大记录大,总体来说,这些页的数据是递增的。

注意!是递增,但是并没有要求顺序递增。

因为对于二分查找法来说,只要数据是有序递增的,就可以保证其快速查找到我们需要的数据了。

以查找id=8的记录为例,首先在根节点通过二分查找法找到记录5,对应的页号是28,然后找到页28,通过二分法找到主键为8的记录。

现在回到我们的问题,雪花算法生成的id会对MySQL性能造成影响吗?

雪花算法的一大特性是什么呢?

大致递增。

换句话说,只要是递增的,哪怕我们用JAVA的AtomicInteger或者通过redis的incrmentBy来生成主键id也没问题。

雪花算法就不过多介绍了,有想了解的朋友可以看一下这篇文章。[雪花算法介绍]。

另外再多说一句:MySQL自增主键虽然申请时是表级全局递增的,但是最后保存到表中就不一定了。

举个简单的例子,批量保存10条数据,由于某些原因,这个事务操作回滚了。当你再插入一条数据时,你会发现上次申请的10个id已经被浪费掉了,表中的id是从11开始的。

MySQL的数据结构和索引是一个庞大的系统,很难通过一篇简单的文章将其彻底讲清楚,如果你对本文有不同见解,也欢迎在评论区交流。

文中图片来自网络,侵删。

参考:高性能MySQL、MySQL是怎样运行的等。

感谢您的点赞和关注。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux 系统运维基础】Linux目录 以及重要配置文件

Linux目录 以及重要配置文件 文本讲述了Linux中目录含义 以及我们工作中常用到的路径 1. 目录含义 2. 常用路径地址 2.1 网卡配置文件 /etc/sysconfig/network-scripts但是网卡的名称是有区别的,使用不同服务器生产商的名称是不同的。如下图: 网卡配置…

Window10下FFMPEG的安装与使用

文章目录一.FFMPEG介绍FFMPEG组成二.Windows10下FFMPEG安装三.FFMPEG的使用1.关键指令一.FFMPEG介绍 FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它…

字节前端面试题目2

1.为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片? 1. 没有跨域问题,一般这种上报数据,代码要写通用的;(排除 ajax) 2. 不会阻塞页面加载,影响用户的体验,只…

基于SSM的图书购物商城设计与实现

项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下,你想解决的问…

【C++】三大特性之继承

目录 一、继承的概念及定义 1.继承的概念 2. 继承定义 2.1定义格式 2.2继承关系和访问限定符 2.3继承基类成员访问方式的变化 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 五、友元与继承 六、继承与静态成员 七、复杂的菱形继承及菱…

机器学习中的数学原理——线性不可分

这个专栏主要是用来分享一下我在 机器学习中的 学习笔记及一些感悟,也希望对你的学习有帮助哦!感兴趣的小伙伴欢迎 私信或者评论区留言!这一篇就更新一下《 白话机器学习中的数学——线性不可分》! 目录 一、什么是线性不可分 二…

用125行C语言编写一个简单的16位虚拟机

改博文用图文代码的方式详细描述了实现的具体过程,包含每一条指令的含义。 虚拟机 在计算领域,VM(虚拟机)是一个术语,指的是模拟/虚拟化计算机系统/架构的系统。 从广义上讲,有两类虚拟机: 系统…

每日一练11——最近公共祖先求最大连续bit数

文章目录最近公共祖先思路:代码:求最大连续bit数思路:代码:最近公共祖先 题目链接 思路: 题目所描述的满二叉树如下: 上述树中子节点与父节点之间的关系为root child / 2 所以如果a ! b&a…

递归算法整理

一、概述:递归算法是一种直接或者间接调用自身函数或者方法的算法。说简单了就是程序自身的调用。类似于数列,通过前几项的值推出后几项 二、递归算法的使用条件1.大问题可以拆分为若干小问题2.原问题与子问题除数据规模不同,求解思路完全相同…

自助Active Directory组订阅

在任何基于Windows的企业的身份与访问管理(IAM)战略中,Active Directory组扮演了至关重要的角色,因为它们用来控制对几个资源(包括电子邮件通讯组)的用户访问。反复地添加用户到组中和从组中移除用户构成了IT管理员工作的有机组成…

C#windows竞赛管理系统

中文摘要 为了提高竞赛项目信息的管理效率,本课题使用C#语言和SQL Server数据库系统开发了一个WinForm类型的竞赛管理系统对竞赛项目信息进行高效管理,以提升管理质量。本系统包含教师登录注册、教师信息修改模块、添加学生信息模块、删除学生信息模块、…

可编程直流电源的介绍 什么是可编程直流电源

现在各种的电子设备不断地发展,它们对直流供电的电源也有了更高的要求,相对于电子设备来说,用单一的直流电源是没有办法达到供电的要求,所以需要不同的直流电源来给电子设备供电。可编程直流电源就是这一种。在生产测试中&#xf…

java:获取本机IP,Linux环境下使用InetAddress.getLocalHost()方法获得127.0.0.1

知道InetAddress.getLocalHost()方法是可以获取本地ip的,但是在mac电脑上执行的时候,偶尔会得到127.0.0.1的输出,这样拿到本地ip很不稳定,感觉就很不靠谱了 目录InetAddress.getLocalHost()方法获取本地IP不靠谱原因获取本地IP的靠…

Python中最简单不过的print语句讲解

名字:阿玥的小东东 学习:Python、c 主页:阿玥的小东东 前面使用 print() 函数时,都只输出了一个变量,但实际上 print() 函数完全可以同时输出多个变量,而且它具有更多丰富的功能。 目录 1.格式 2.参考 1…

leetcode-每日一题-1334-阈值距离内邻居最少的城市(中等,floyd)

佛洛依德的变化问法,我之前有文章介绍过佛洛依德算法,不难可以去看看。1334. 阈值距离内邻居最少的城市难度中等94收藏分享切换为英文接收动态反馈有 n 个城市,按从 0 到 n-1 编号。给你一个边数组 edges,其中 edges[i] [fromi, …

如何做数据清洗?

一.预处理阶段 预处理阶段主要做两件事情: 一是将数据导入处理工具。通常来说,建议使用数据库,单机跑数搭建MySQL环境即可。如果数据量大(千万级以上),可以使用文本文件存储python操作的方式 而是看数据…

04-jQuery

目录1、jQuery 的属性操作2、jQuery 练习2.1、全选,全不选,反选3、DOM 的增删改4、jQuery 练习二4.1、从左到右,从右到左练习4.2.动态添加、删除表格记录5、CSS 样式操作。6、jQuery 动画练习 6.1、CSS_动画 品牌展示7、jQuery 事件操作7.1、…

vue3+vite+ElementPlus安装和使用

按照vue3官网安装 > npm init vuelatest这一指令将会安装并执行 create-vue&#xff0c;它是 Vue 官方的项目脚手架工具。你将会看到一些诸如 TypeScript 和测试支持之类的可选功能提示&#xff1a; ✔ Project name: … <your-project-name> ✔ Add TypeScript? ……

LeetCode 1252. 奇数值单元格的数目

给你一个 m x n 的矩阵&#xff0c;最开始的时候&#xff0c;每个单元格中的值都是 0。 另有一个二维索引数组 indices&#xff0c;indices[i] [ri, ci] 指向矩阵中的某个位置&#xff0c;其中 ri 和 ci 分别表示指定的行和列&#xff08;从 0 开始编号&#xff09;。 对 in…

《python3网络爬虫开发实战 第二版》之爬虫基础-Web网页基础 详解

文章目录Web网页基础网页的组成HTMLCSSJavaScript网页的结构节点树及节点间的关系选择器写在最后Web网页基础 用浏览器访问不同的网站时&#xff0c;展现的页面各不相同。下面从网页的组成、网页的结构、节点树及节点间的关系、选择器几个方面了解网页。 网页的组成 网页可以…