我跟面试官说MySQL单表数据量不要超过两千万,面试官不信

news2024/10/5 17:19:04

61e42b5fa020806a9bec1bd67a4fad31.png

86dc9c6cc91c2ba8fedeaac374507a4c.gif

👉导读

作为一个合格的 DBA,在遇到线上单表数据量超过千万级别的时候,往往会建议用户通过分表来缩减单表数据量,当用户问为什么单表数据量不能超过千万时,DBA 往往会说:单表数据量超过千万,会影响查询性能。知其然而不知所以然,学习技术不能停留在表面,而是要进一步去深入挖掘其中的原理,这样才能不断进步和成长。回到这个问题:为什么单表数据量不能超过两千万,其中的依据是什么?欢迎阅读。

👉目录

1 自增主键角度

2 数据页角度

3 思考

事情是这样的:

小王最近参加了腾讯的技术面试,面试官向他提了一个经典的面试问题:聊聊你日常项目里的分库分表实践?

于是小王以过往项目里的某个 case 为例做了回答:

我负责的项目里涉及到存储用户操作记录的功能,因为每天的数据量比较大,差不多超过 5000 万条,所以我另外又做了分库分表的操作。系统会自动定时生成 3 张表,数据分别存储其中,防止都放在一个表里面导致查询性能降低。

面试官又问:这里为什么要做一个分库分表的操作呢?如果放在同一张表里面,为什么会导致查询性能降低?

小王内心 OS:为什么1+1=2?但他还是语气平常地回答说:

MySQL 单表不要超过 2000 万行基本上是一个行业共识,只有当单表行数超过 500 万行或者单表容量超过 2GB,我们一般才推荐进行分库分表。

面试官点了点头表示认可,却也没有在这个问题上继续深究,继而问起了别的问题,不久后就结束了面试。小王回过神来以后复盘这次面试过程,觉得自己在 MySQL 分库分表问题上没有回答得特别到位,于是他开始进一步地深究起来这个“1+1=2”的问题。

01

自增主键角度

我们先来看看单表数据量理论上最大值是多少?

假设我们建表,ID 是自增主键,也就是说主键的大小可以限制表的上限。如果主键声明为 int 类型,那么 int 类型最大为2的32次方 – 1 ,也就是21亿左右;

如果主键声明为 bigint 类型,那么 bigint 类型最大为2的64次方 – 1,这个数字实在太大了,一般还没到这个限制,磁盘就撑不住了;

如果主键声明为tinyint类型,那么 tinyint 类型最大为2的8次方 – 1,也就是255,所以如果我插入一条 ID=256 的数据,就会报错;

上面是从自增主键的角度来讲述单表最大数据量理论上能达到多少,那么接下来从另一个角度“数据页”来阐述一下,单表数据量最大能达到多少,依据是什么?

02

数据页角度

假设我们有一张 user 表,其中 ID 是自增主键,那么该表在硬盘文件上是 user.ibd(innodb 数据文件,又叫表空间文件)。这个数据文件被划分成很多的数据页,每个数据页大小是16K。

4ef3f486369635aa074384f68ec72cfb.png

▶︎ 一个数据页16K,表的数据量很多,一个数据页可能放不下那么多数据,所以数据被分成好多份,存放在不同的数据页,为了标识具体是哪一个数据页,所以需要有页号来标识;

▶︎ 同时为了把这些存放数据的数据页关联起来,又引入了前后指针,用于指向前后的页;

▶︎ 数据页需要读写,写入到一半的过程中可能会发生了意外断电等情况,所以为了保证数据页的准确性,还引入了校验码;

▶︎ 同时为了在数据页搜索数据提高效率,数据页内部还生成了页目录;

▶︎ 除了上述所说的,数据页内剩下的空间就用来存放实际的数据;

即数据页的结构如下:

f4c747d2a3ecfbe08906e3155208c69a.png

数据是以数据页的形式进行存储,数据页和数据页之间是以B+树的形式进行关联,例如:

93edb3c38fb1389aae264fa555f73d37.png

其中,叶子节点的数据页存放的是实际存储的数据,非叶子节点存放的是索引内容。B+树的每一层代表一次磁盘 IO。举个例子,如果我要寻找 ID=5 的记录,从顶部非叶子节点开始查找,由于 ID=5 大于1并且小于7,故应该往左边寻找,来到页号为6的数据页,由于5大于4,故应该往右边寻找,来到页号为105的数据页,找到 ID=5 的记录,完成查询。这个过程中查询了三个数据页,如果这三个数据页都没有加载到内存,那么就需要经历三次磁盘 IO 查询。

了解完 B+树是如何存储数据的,我们就可以开始进行数据的估算。

5a912b401d2bb66d805091baba8a5d14.png

假设:非叶子节点内指向其他数据页的指针数量为 X(即非叶子节点的最大子节点数为 X);每个叶子节点可以存储的行记录数为 Y;B+树的高度为 N(即  B+树的层数);

  • 对于一个高度为 N 的 B+树,顶层(根节点)有一个非叶子节点,那么第二层就有X个节点,第三层就有 X 的2次方个节点,第四层就有 X 的三次方个节点,以此类推,第 N 层(即叶子节点所在的第 N 层)就有 X 的 N-1 次方个节点;

  • 在 B+ 树中,所有的记录都存储在叶子节点中,假设每个叶子节点都可以存储的行记录数为 Y;

  • 那么 B+ 树可以存储的数据总量为叶子节点总数乘以每个叶子节点存储的记录数,即:M=(X 的 N-1 次方)乘以 Y;

代入计算:

  • 一个数据页大小16K,扣除页号、前后指针、页目录,校验码等信息,实际可以存储数据的大约为15K,假设主键ID为bigint型,那么主键 ID 占用8个 byte,页号占用4个 byte,则 X=15*1024/(8 + 4) 等于1280;

  • 一个数据页实际可以存储数据的空间大小,大约为15K,假设一条行记录占用的空间大小为1K,那么一个数据页就可以存储15条行记录,即 Y=15;

  • 假设 B+树是两层的:则 N=2,即 M=1280的(2-1)次方 * 15 ≈ 2w ;

  • 假设 B+树是三层的:则 N=3,即 M=1280的2次方 * 15 ≈ 2.5 kw;

  • 假设 B+树是四层的:则 N=4,即 M=1280的3次方 * 15 ≈ 300亿 ;

综上所述,我们建议单表数据量大小在两千万。当然这个数据是根据每条行记录的大小为 1K 的时候估算而来的,而实际情况中可能并不是这个值,所以这个建议值两千万只是一个建议,而非一个标准。

03

思考

最后考一个问题:一个4层的 B+树,主键是 bigint 型,一条记录平均长度是1K,不考虑碎片,能存放多少条记录?

答案:

根据 B+树存储数据的计算公式:M = X 的 N-1 次方 * Y:

一个数据页大小16K,扣除页号、前后指针、页目录,校验码等信息,实际可以存储数据的大约为15K,假设主键 ID 为 bigint 型,那么主键 ID 占用8个 byte,页号占用4个byte,则X=15*1024/(8 + 4) 等于1280;

每条记录1K大小,一个数据页有15K是用来存储数据的,那么一个数据页就能存储15条记录;

所有叶子节点数量为 X 的 N-1 次方,即1280*1280*1280;存储的记录数总数为:叶子节点数量 * 每个叶子节点存储的记录数,所以 M = 1280*1280*1280*15。

以上就是本文的全部分享,如果对你有帮助,欢迎转发分享。

你,学会(废)了吗

-End-

原创作者|肖浩腾

dbd154246015d4ba7d349bee0800ac08.png

MySQL 还有什么方法优化查询性能?欢迎分享。我们将选取1则最有意义的评论,送出腾讯云开发者-手提袋1个(见下图)。9月21日中午12点开奖。

a028f364ff98af30124f03bd0837ac96.png

📢📢欢迎加入腾讯云开发者社群,社群专享券、大咖交流圈、第一手活动通知、限量鹅厂周边等你来~

ce8037f93b664f4fb5052b5cb8af904b.png

(长按图片立即扫码)


dd50a3a7349eccbcfb6744faa8bc103b.png

091e23c6fc3fec87932558283262771a.png

db46db831605910e4d9262b7fd485ab5.png

3c9cd8a64fbd25b275169fac716c80cf.png

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

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

相关文章

搜好货API接口解析,实现获得搜好货商品详情

要解析搜好货API接口并实现获取搜好货商品详情,你需要按照以下步骤进行操作: 了解搜好货开放平台:访问搜好货开放平台官网,找到API接口相关的开发者文档、指南等信息。注册开发者账号:在搜好货开放平台上注册一个开发…

C#开发的OpenRA游戏之调试菜单2

C#开发的OpenRA游戏之调试菜单2 前面已经分析了怎么样通过选项参数来打开这个调试界面,当创建游戏之后,从游戏里选择参数按钮,就会弹出下面的界面,如果没有选择调试参数是没有Debug这一页选项卡: 上面调试的选项是非常有用的,否则不能快速地测试游戏,不能快速地开发新的…

列表页面新增 字段查询 ,点击查询后,前端页面和后端控制台 出现红色报错信息,查询数据失败。

项目场景&#xff1a; 项目场景简述&#xff1a; 列表页面新增 字段查询 &#xff0c;点击查询后&#xff0c;前端页面和后端控制台 出现红色报错信息&#xff0c;查询数据失败。 问题描述 问题描述&#xff1a; <el-select v-model"dataForm.engineerId" clea…

类和对象(4)

文章目录 1. C/C内存分布2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free3.C内存管理方式new/delete3.1 new/delete操作内置类型3.2 new/delete操作自定义类型 4. operator new和operator delete函数&#xff08;重点&#xff09;4.1底层原理 5.malloc/free…

24届双非本科找工作到底有多难

记录一下自己的找工作过程&#xff0c;今天笔试失败感觉整个人都颓废了(那家公司真的是我的目标情司&#xff0c;呜呜呜&#xff0c;感觉我是废物)。 再加上不考虑出省&#xff0c;感觉找工作太难了 介绍一下自己情况&#xff1a;三个省奖&#xff08;开发类的&#xff0c;负责…

性能测试模型-业务模型、策略模型、数据模型

针对性能测试具体方案的设计进行抽象和总结,将其归纳为6个性能测试模型。 业务模型 业务模型是一组功能点或接口的集合及其占比情况,用于合理地模拟生产上真实的业务发生场景 在实施范围上,业务模型为本项目明确实施范围,梳理涉及的业务系统及其完整链路等 在实施结果价值…

提示词加神秘咒语让大模型更加聪明

谷歌团队研究发现&#xff0c;提示词加上神秘咒语深呼吸(take a deep breath&#xff09;结合大家已经熟悉的“一步一步地想”&#xff08;Let’s think step by step&#xff09;&#xff0c;大模型在数据集上的成绩就提升了12%。而且这个最有效的提示词&#xff0c;是AI自己找…

bug总结问题集和知识点集(一)

目录 一 bug问题集1. 端口被占用 二 oracle1. oracle查看版本怎么操作2. oracle数据库&#xff1a;参数个数无效![在这里插入图片描述](https://img-blog.csdnimg.cn/6a2eebc164f9406c81525371893bbd11.png)3. ORACLE数据库如何完整卸载? 三 mybatis1. mybatis用注解如何实现模…

算法|图论 6 并查集

并查集基本模板&#xff1a; int n 10; vector UFSets(n,0);//若将初值全设置为-1&#xff0c;那就不用再有初始化操作了。//初始化 void Initial(vector<int> S[]){for(int i0;i<n;i){S[i] -1;} }//查操作 int Find(vector<int> &S,int x){int root x;…

【红包雨压测环境】

文章目录 红包雨压测环境并发预估积分与权重对于新用户&#xff0c;活跃度占比为70%&#xff0c;贡献度占比为30%。活跃度权重分配&#xff1a;贡献度权重分配&#xff1a; 对于高质量作品的作者&#xff0c;活跃度占比为30%&#xff0c;贡献度占比为70%。活跃度指标权重&#…

杭州企业型通配符SSL数字证书

通配符SSL数字证书是众多数字证书产品中比较特殊的一款产品&#xff0c;在互联网安全领域&#xff0c;SSL数字证书是保障网站安全性的一种重要手段。而通配符SSL数字证书&#xff0c;更是其中的一种特殊类型&#xff0c;它允许用户对多个域名进行保护&#xff0c;只需一张证书即…

C++--简单实现定长内存池

1.什么是定长内存池 在C/C中&#xff0c;动态申请内存都是通过malloc来申请的&#xff0c;但是实际上不是是直接从堆上直接申请的内存&#xff0c;而是通过malloc动态申请一大块内存&#xff0c;malloc就相当于一块内存池&#xff0c;然后分给程序使用&#xff0c;如果申请的内…

网络安全进阶学习第十六课——业务逻辑漏洞介绍

文章目录 一、什么是业务逻辑二、业务逻辑漏洞的成因三、逻辑漏洞的重要性四、业务逻辑漏洞分类五、业务逻辑漏洞——业务授权安全1、未授权访问2、越权访问1) 平行越权&#xff08;水平越权是指相同权限的不同用户可以互相访问&#xff09;2) 垂直越权&#xff08;垂直越权是指…

企业架构LNMP学习笔记47

企业架构队列缓存中间件分布式redis&#xff1a; 一直想学习下这块的。今天总算学到了&#xff0c;好好把redis的这块内容理解下。 1&#xff09;能够描述Redis作用及其业务适用场景 &#xff1b; 2&#xff09;能够安装配置启动Redis&#xff1b; 3&#xff09;能够使用命令…

Qt使用注意事项

1.菜单选项不能出现数字&#xff0c;可以是 英文 加 “_”&#xff1a; 2.如何确保加载的图片&#xff0c;尺寸大小与原来一样&#xff1f; 【QT】添加图片资源并使用QImage加载图片显示_qimage显示图片_李春港的博客-CSDN博客 ui->PicLabel->setPixmap(QPixmap::fromIm…

(9.8-9.14)【大数据新闻速递】

加gzh“大数据食铁兽”&#xff0c;了解更多大数据快讯 【2023百度十大科技前沿发明】 近日&#xff0c;百度发布了“2023百度十大科技前沿发明”&#xff0c;包括“基于大模型的检索生成决策交互一体的智能系统”“基于大模型的端到端搜索技术”“飞桨端到端自适应的分布式训…

网络工程师的甩锅指南,果断收藏

大家好&#xff0c;我是老杨。 都说IT行业最容易被甩锅的就是网工&#xff0c;这是有科学依据的&#xff0c;比如&#xff1a; 纵观我网工群的群友聊天&#xff0c;“锅”不离口&#xff0c;很难不说明一点什么问题。 遇到甩锅&#xff0c;我相信没有哪位朋友的心情是愉悦的。…

父子工程搭建

1. 构建父工程 父工程的职责是对依赖包的版本进行管理&#xff0c;创建父工程分两步&#xff0c;第一创建父工程&#xff0c;第二在pom.xml编辑依赖管理。 进入新建模块界面&#xff0c;选择Spring Initializr&#xff0c;填写模块的信息&#xff1a; 创建成功&#xff0c;删…

linux服务器内服务访问域名Name or service not know

目录 linux服务器内服务访问域名Name or service not know 1.前言2.排查是不是这个域名无法访问2.1服务内ping 这个域名2.2在浏览器打开这个域名2.3服务内ping 这个域名所对应的ip2.4在服务器内配置host 总结参考 文章所属专区 项目问题解决 1.前言 linux服务器内服务访问域名…

许可分析 license分析 第五章

许可分析是指对软件许可证进行详细的分析和评估&#xff0c;以了解组织内部对软件许可的需求和使用情况。通过许可分析&#xff0c;可以帮助组织更好地管理和优化软件许可证的使用。以下是一些可能的许可分析方法和步骤&#xff1a; 软件许可证自动化管理&#xff1a;考虑使用自…