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

上传人:太** 文档编号:39466771 上传时间:2022-09-07 格式:DOCX 页数:8 大小:242.25KB
返回 下载 相关 举报
MySql数据是如何存储在磁盘上存储的.docx_第1页
第1页 / 共8页
MySql数据是如何存储在磁盘上存储的.docx_第2页
第2页 / 共8页
点击查看更多>>
资源描述

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

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主从复制的一个很重要的文件)索引元组格式:InnoDB存取过程记录的中间状态,是InnoDB在内存中

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

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

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

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

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

8、么回事,然后在慢慢的挖掘,我们一定要一个萝卜一个坑的去踏实学习现在如果是多个varchar类型的字段怎么办?例如:varchar (3), varchar (10) , varchar (4) , char (1),他有一条记录是这样子的: aaa , bb, cccc, d,你根据上面的能推测出磁盘中的行记录是怎么样子的吗? 你是不是这么想的:磁盘中肯定是这样的:0x03, 0x02, 0x04 null标志位 记 录头信息 aaa bb cccc d;这么想的同学请鼻子靠墙:);实际上并不是这 样子的。当有多个变长字段的时候,MySql在compact行格式中,把所有变长类型的长度存放在行

9、记录的开头部位形成一个列表(这个列表就是刚刚上 面说的变长字段列表),按照列的逆序存放,也就是大致是这样子的:0x04 0x02 0x03NULL标志位记录头信息aaabbcccc这里我必须要给大家解释下变长字段列表会逆序存放,因为每行记录的都有 一个 next_record指针指向下一行记录头信息和真实数据之间的位 置。因为这个位置刚刚好,向左读取就是行描述相关信息,向右读取就是真 实数据。正好对应变长字段长度列表。画个图来帮助大家理解下:以第二条记录为为例:我们可以看到指针指向的,演,往左找到变长字段列裳依次是0x02 0x03 0x01.往右找到数霜部分依次是:abbb cc;刚好从右到

10、左长度分别是1 3 2 ,右立的数据从左到右李苻长度分别是:1 3 2.完美对接上0x02 0x03 0x01NULL标志位|记录头信学拒向下一0x04 0x02 0x03NULL标志位记录头信惠aaa输司下_0x03 0x01 0x02NULL标取立记录头值患aa说到这里我们来稍微小结一下MySql中数据在磁盘的存储小结1. 数据在磁盘中的存储在物理空间上面是连续的数据是被存放在MySql设计出来的数据页上面的,数据页上面存储的 才是最终的一行一行的记录2. 行的存储格式默认是Compact每一行数据都会有相应的行描述部分,描述部分有【变长字段列表】NULL标志位】【记录头信息】每一行都会有

11、next_record指针,指向记录头和变长字段列表的中间某个位置,方便寻址变长列表中的varchar列的描述是逆序的(和字段的顺序相反)这样做的目的在上图中描述的很清楚了NULL字段是如何存储的上面说到了情况都是比较正常的情况,也就说上面提到 的字段是没有空值的,不管是变长字段还是char字段,都是有值的,那如果 某个字段允许为空,且值确实为空,MySql又是怎么处理的呢?是不是直接 存储NULL呢。假设MySql针对与Null直接存储,他实际上是按照“ NULL ” 这样字符串的形式存储的,这样显然不行啊,因为字符串要占用空间的啊(一 个NULL字符串要占用四个字符呢),你都没有值,还占这

12、么多空间,所以 MySql肯定不是这样存储的。其实MySql在处理NULL值的时候是会将它通二 进制来存储的,且也是逆序的MySql是如何通过二进制来存储NULL值的?上面的Compact格式数据中的NULL标志位(也可以叫NULL列表)】就是用来存储NULL值的。若有某个 字段值为null,将将其bit位置为1说明值为NULL, bit为0说明该 字段值不为空是不是听了解释还是稀里糊涂的,别急,我画个图再来详细介 绍下,先假设我们有一张sutdents表CREATE TABLE students (name varchar (10) NOT NULL,address varchar (255

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

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

15、not nul 1的字段 是不会去存放在null标志位的,下面是详细的读取步骤: name字段是主键,不可能在NULL标志位中的,又因为name是varchar字段,所以就会去变长字段列中查找,找到值为0x05接着就会去字段列表中读取5个字符的长度,也就是roles ,第一个字段读取成 功;接着是address字段,因为类型是MySql已知的,又因为字段值为 null所以就不需要去读取了,第二个字段读取结束; 接着是gender字段,是char类型的,直接拿到f就可以了;下一个是class字段,因为是null所以根本不会去变长字段中查找; 最后一个是hobbies字段,因为不为null ,又是

16、第二个变长字段,这个时候就会去 变长字段列表中查找,结果定位到是0x08那就读取8个字符的长度出来,拿出来是hobby_xx;说到这里,关于一行记录的中的变长字段列表和NULL标志位具体是如何读 取字段值的就给大家介绍完了,不知道大家看到以上内容脑子是不是会展现 一条条行记录的描述信息。目前我们只需要了解varchar和NULL存储的 基本就足够了,因为这两个表特殊,也是最经常使用的,其他的字段类型本 篇暂且不展开讨论了。上面的记录头的信息我们还没有讨论过,下面我们再 详细介绍下记录头信息是什么。记录头信息记录头信息由40位的bit位组成,其各个位的划分和含义如下:bit位名称作用预留位没有作

17、用预留位没有作用1316delete mask删除标志位min rec maskn ownedheap_norecord.typenext recordB+树的每一层的非叶子节点的最小值有会有这个标志当前记录拥有的记录数示意当前纪录在纪录堆的位置信息标识当前纪录的类型:。代表的是通俗类型,1代表的是B+树非叶子节点,2代表的是最小值数据,3代表的是最大值数据。示意下一条纪录的相对位置记录头的各个位的作用其实就已经说的很清楚了,一些概念现在还没法讲解, 很多东西需要到索引的时候才能展开讲,这里大家需要明确的就是各个标志 位的含义。我认为对于记录头的了解到这里就足够了,各个标志位的含义明 确了到这

18、个程度就行了,至于更多的可能我们根本接触不到。这一小节就当 是科普。数据在磁盘上到底是怎么存储的上面画过这样一张图:0x03NULL标志位记录头信息dogbc之前说的是数据大致是这样子在磁盘中存储的:0x03 NULL标志位记录头信 息dog b c,但是实际上后面的列的数据并是不是我们看到的这个样子,磁 盘在存储的时候是根据数据库指定的字符集编码存储起来的你以为可能是上 面那样子存储的。实际上可能是在样子的:0x03 NULL标志位 记录头信息 1233 323 223,也就是说实际的数据在磁盘上存储根本不是我们人能认识的, 后面的1233 323 223这几个是我乱写的,没什么含义,主要是

19、想表明是计 算在实际存储的时候是以特定的字符编码来存储的。另外每一行数据在被存 储的时候实际上还会有隐藏的字段,相信大家对这个应该不会陌生的,row_id 大家应该是知道的,哪怕自己没用过可能也是听过的,这个是数据库自己为 我们的每一行记录生成的一个唯一的表示,如果我们没有为数据表指定主键 字段,也没有指定Unique key,那么这个时候数据库内部会帮我们维护一个 自增长的R0W_ID字段作为主键。还有一个隐臧字段就是事务ID上面的第 二张图上层画出来过,这个顾名思义了,就是和事务相关的一个字段属性字 段名为DB_TRXD,这个再详解到事务的时候再详细介绍;最后一个也是在 上面的第二张图上画

20、出来了,就是回滚指针DB_R0LL_PTR,回滚也是事务使 用到的概念,也是放在事务那边跟大家介绍现在再来整体回顾下一行记录在 磁盘中的存储的结构大概是什么样子的:0x080x05 232343说到了存储,我们顺便聊聊和存储相关的一个概念,行溢出。行溢出说到这里,不知道大家有没有想过一个问题,就是我们一直在说MySql 存储是以数据页的形式来存储的,然后数据页中记录的是一行行的记录,但 是往往常规情况下不会有什么问题。但是如果现在有一行记录非常大,因为 数据页大小默认也就是16KB,假设某张表里面有text字段也有BLOB字段, 且这一行的记录的大小远远超过了一个数据页的大小16KB,这种情况

21、称之为 行溢出。MySql是怎么来处理这种行溢出的情况的呢?实际上很简单,一个 数据页不够就使用多个数据页,数据页和数据页之间使用链表连起来,之所 以能够使用链表连接因为数据页里面是包含了存放指针的bit位。对于行溢 出的概念了解到这个程度就足够了。我们学习是有的放矢,不是什么都要去 刨根问底的。结束语本片文章详细的介绍了 MySql存储数据的格式和数据具体在磁盘中 是怎么存储的,被存储的数据又是怎么查找的,说白了很多事情都是已经是 既定的规则,所谓既定的规则就是很对东西已经被更早的设计出来。所以你在使用和了解的使用只需要按照被人的规则来执行,然后在此基础上深入了解下别人为什么这么设计?这样会更有助于我们掌握和理解某个知识点。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 应用文书 > 解决方案

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com