MySql数据是如何存储在磁盘上存储的.docx

上传人:lao****ou 文档编号:136929 上传时间:2023-04-10 格式:DOCX 页数:11 大小:422.47KB
下载 相关 举报
MySql数据是如何存储在磁盘上存储的.docx_第1页
第1页 / 共11页
MySql数据是如何存储在磁盘上存储的.docx_第2页
第2页 / 共11页
MySql数据是如何存储在磁盘上存储的.docx_第3页
第3页 / 共11页
MySql数据是如何存储在磁盘上存储的.docx_第4页
第4页 / 共11页
MySql数据是如何存储在磁盘上存储的.docx_第5页
第5页 / 共11页
亲,该文档总共11页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《MySql数据是如何存储在磁盘上存储的.docx》由会员分享,可在线阅读,更多相关《MySql数据是如何存储在磁盘上存储的.docx(11页珍藏版)》请在第一文库网上搜索。

1、MySql数据是如何存储在磁盘上存储的?敖丙 2021-06-04 08:54以下文章来源丁 Hollis ,作者zyzl992Hollis.Hollis, 一个对Coding有着独特追求的人。Java工程师成神之路系列作者、程序员的三门课联合作者,本公众号专注分享Java相关技术干货!关于MySql数据库,相信很多人都不陌生,这是当今最常用的一种关系型数据库,关于MySql的知识也是很丰富的。那么,不知道大家有没有想过这样的问题:MySql中的数据是存在哪的? 乂是如何存储的呢?本文就来深入分析一下这些问题。文章内容很长,建议收藏,建议大家静下心来仔细阅读,一定会有收获!Innodb的存储格

2、式我们知道,关于Mysql这种关系型数据库,里面保存的数据最终都是要持久化到磁盘文件上面的。磁盘文件里存放的物理格式就是数据页(关于数据页,如果不太理解先忽略,后续文章单独介绍),数据页中存放的是一行一行的记录,但是对于数据页中的每一行数据他又是怎么存储的呢?我们拿Mysql中最常用的Innodb引擎来重点说,介绍下存储格式是怎样的。MySQL中存储有3种:1. server层格式:与存储引擎无关,Binlog存储常用的一种(Bin Log我们前面已经详细介绍过了,这个是MySql主从复制的一个很重要的文件)2. 索引元组格式:InnoDB存取过程记录的中间状态,是InnoDB在内存中存储的格

3、式 (换句话说我们的增删改的操作都是在内存中执行的,这个只是一种临时状态)3. 物理存储格式:记录在物理页面中的存储格式,即compact格式,与索引元组格式一一对应。(这个是数据在磁盘存储的真正的格式)MySql的InnoDB存储引擎和大多数数据库一样,都是以行的形式存储数据的,我们可以通过SHOW TABLE STATUS查看到行的的存储格式。InnoDB储存引擎支持有四种行储存格式:COMPACT、Redundant、Dynamic和COMPRESSED。默认为COMPACT o 其他的参数我们这里不关注,仅仅看Row_format这列,这里我们可以看到行的存储格式是Compact, C

4、ompact存储数据的格式大致如下这样变长字段长度列表NULL标志位记录头信息事务ID回滚指针列1数据列对于我们看到的每一行数据,我们最先看到的好像并不是各个列,而是一些类似列的描述信息。没错,其实在存储的时候都会有一些都字段来描述这一行的信息,这就好比缓存池中的描述缓存页的描述数据类似。卜 .面的图片大家可以这么简化来对待,事务ID和回滚指针大家先不要关注,免得因为这个产生干扰而难于理解变长字段长度列表NULL标志位记录头信息列1数据列2数据变长字段varchar是如何存储的一般情况下,我们要存储的数据是并不能确定他的长度的,大部分情况下都是一些变长的数据,以varchar为例,假设现在三个

5、字段,字段类型分别为:varchar (10), char (1), char (1) , char大家都是知道的,存储的基本是一些已知的长度固定的数据,假设这三个类型的字段分别有如下的数据:第一行:mysql a a;第二行:dog b c;画个图来帮助大家想象,现在你看到的是数据中为我们展现的样子。varchar(10) char(1)char 第一行第二行但是在磁盘中可不是这样子的,前文已经提到过,表空间和行这些其实是逻辑上的概念,而数据页是一种物理概念,也就是说我们看到的样子在磁盘中的样子本本是不一样的。在磁盘中这两条记录大致是这样子的:mysql a a dog b c,他们在磁盘中

6、都是挨在一起存储的。是不是瞬间感觉想要去查找一条数据非常麻烦,告诉你:是的,所以MySql在设计的时候才会使用行格式存储,才会有前面的哪些变长字段列表和标志位以及记录信息、,这些就是用来记录一行的记录的信息,换句话说,MySql是通过这些描述信息来定位到一行中的具体记录的。以第一行记录为例,它在磁盘中的记录情况大致是下面这样子的,首先我们需要明确知道的是各个字段的类型MySql是很清楚的,在这个基础上我们能看明白下面和想通后面的事情。首先我们看到 mysql是5个字符,使用十六进制表示是0x05,所以他的存储大概是这样子的:0x05NULL标志,立I记录头信息mysqlaa同理第二行数据类似这

7、样子的:0x03NULL标志位记录头信息dogb相信大家在看到这里已经大概能推测出MySql这个时候是怎么读读取数据的了,就是他会先根据变长字段长度列表中描述的变长字段的信息去查找变长字段,例如第一行,MySql解析到变长字段是5,所以他会在mysql a a dogb c这些里面取出5个字符,也就是 mysql,紧接着后而是两个char(l)也就是两个 a在依次取出来。中间设备。由浅入深,我们慢慢来,刚刚上面说到的仅仅是一种非常简单的情况,这个首先是帮助大家理解,让大家先明白有这么个回事,是这么回事,然后在慢慢的挖掘,我们一定要一个萝卜一个坑的去踏实学习现在如果是多个varchar类型的字段

8、怎么办?例如:v a r c h a r (3) , varchar (10), varchar(4), char (1),他有一条记录是这样子的:aaa , bb, cccc, d,你根据上面的能推测出磁盘中的行记录是怎么样子的吗?你是不是这么想的:磁盘中肯定是这样的:0x03, 0x02, 0x04 nul 1标志位 记录头信息 aaa bb cccc d;这么想的同学请鼻子靠墙:);实际上并不是这样子的。当有多个变长字段的时候,MySql在compact行格式中,把所有变长类型的长度存放在行记录的开头部位形成一个列表(这个列表就是刚刚上面说的变长字段列表),按照列的逆序存放,也就是大致是

9、这样子的:0x04 0x02 0x03NULL标志位记录头信息aaabbcccc这里我必须要给大家解释下变长字段列表会逆序存放,因为每行记录的都有一个 ncxt_rocord指针指向下一行 记录头信息和 真实数据 之间的位置。因为这个位置刚刚好,向左读取就是行描述相关信息,向右读取就是真实数据。正好对应变长字段长度列表。画个图来帮助大家理解下:0x04 0x02 0x03NULL位记录头信息aaa向下一以第二条记录为为例:1我们可以看克指针指向的位置,往左找到变 X长字段列表依次是0x02 0x03 0x01 ,往右找0x02 0x03 0x01NULL标志位记录头信a三境日三二蜜是:工;二苫

10、= 左长度分别是1 3 2 ,右边的数据从左到右字符长度分别是:1 3 2.完美声接上0x03 0x01 0x02NULL标志位记录头值星说到这里我们来稍微小结一下MySql中数据在磁盘的存储小结1. 数据在磁盘中的存储在物理空间上面是连续的2. 数据是被存放在MySql设计出来的数据页上面的,数据页上面存储的才是最终的一行一行的记录3. 行的存储格式默认是Compact4. 每一行数据都会有相应的行描述部分,描述部分有【变长字段列表】NULL标志位】【记录头信息】5. 每一行都会有ncxt_rccord指针,指向记录头和变长字段列表的中间某个位置,方便寻址6. 变长列表中的varchar列的

11、描述是逆序的(和字段的顺序相反)这样做的目的在上图中描述的很清楚了NULL字段是如何存储的上面说到了情况都是比较正常的情况,也就说上面提到的字段是没有空值的,不管是变长字段还是char字段,都是有值的,那如果某个字段允许为空,且值确实为空,MySql又是怎么处理的呢?是不是直接存储NULL呢。假设MySql针对与Null直接存储,他实际上是按照“ NULL ”这样字符串的形式存储的,这样显然不行啊,因为字符串要占用空间的啊(一个NULL字符串要占用四个字符呢),你都没有值,还占这么多空间,所以MySql肯定不是这样存储的。其实MySql在处理NULL值的时候是会将它通二进制来存储的,且也是逆序

12、的MySql是如何通过二进制来存储NULL值的?上面的Compact格式数据中的NULL标志位(也可以叫NULL列表)】就是用来存储NULL值的。若有某个字段值为null,将将其bit位置为1说明值为NULL, bit为0说明该字段值不为空是不是听了解释还是稀里糊涂的,别急,我画个图再来详细介绍下,先假设我们有一张sutdents表CREATE TABLE studentsnamevarchar(10) NOT NULL,address varchar (255) DEFAULT NULL,gender char(1) DEFAULT NULL,_class varchar(10) DEFAU

13、LT NULL,hobbies varchar (255) DEFAULT NULL,PRIMARY KEY (name:)他有这样一行记录 我们先看变长字段列表部分(记住是逆序存放的):roles是长度为5记作:0x05; address为null,不放在变长列表中、gender是char类型,不放在变长列表中、class为空,不放在变长列表中、hobby_xx长度为8记作:0x08;所以变长列表的记录为:0x08 0x05现在到了 NULL标志位了:依旧是从右往左记录字段:name在设计的时候就是not null,所示是不会出现在NULL标志为中(Null标志为是用来记录字段可为NULL的

14、字段,字段不可以为NULL的不是会被记录到NULL标志位的),address为NULL记作 1, gender 不为 null 记作 0, class 为 null 记作 1, hobbies 不为 null记作0;所以按照字段的顺序结果就是:0101,但是NULL标志位是逆序的,所以NULL标志位存放的结果大概是这样子的:0101,高位补0即可 我们来模拟读取下这条记录:MySql对于字段的类型一定是已知的(这个是在创建数据表的时候就已经定下来了),所以对于name这种not nul 1的字段是不会去存放在null标志位的,下面是详细的读取步骤: name字段是主键,不可能在NULL标志位中

15、的,又因为name是varchar字段,所以就会去变长字段列中查找,找到值为0x05接着就会去字段列表中读取5个字符的长度,也就是roles ,第一个字段读取成功;, 接着是address字段,因为类型是MySql已知的,又因为字段值为null所以就不需要去读取了,第二个字段读取结束;, 接着是gender字段,是char类型的,直接拿到f就可以了;, 下一个是class字段,因为是null所以根本不会去变长字段中查找;, 最后一个是hobbies字段,因为不为null ,又是第二个变长字段,这个时候就会去变长字段列表中查找,结果定位到是0x08那就读取8个字符的长度出来,拿出来是hobby_xx;说到这里,关于一行记录的中的变长字段列表和NULL标志位具体是如何读取字段值的就给大家介绍完了,不知道大家看到以上内容脑子是不是会展现一条条行记录的描述信息。目前我们只

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 应用文档 > 汇报材料

copyright@ 2008-2022 001doc.com网站版权所有   

经营许可证编号:宁ICP备2022001085号

本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有,必要时第一文库网拥有上传用户文档的转载和下载权。第一文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知第一文库网,我们立即给予删除!



客服