MySQL深度剖析之数据在磁盘上存储(2021)
一 数据在磁盘上存储格式(row format)
表中的数据在磁盘上存储是有格式的,可以在创建表的时候通过row_format指定,比如MySQL5.0之前的reduntant,MySQL5.0 之后的compact和dynamic,两个差不多,区别在于页面溢出处理上,还有compressed,在dynamic基础上使用了压缩算法,MySQL5.7 默认就是dynamic,我们这里以compact举例子,它格式如图所示:
二 变长字段长度列表
MySQL表中有些字段长度不固定,是动态的,比如varchar,而tinyint smallint int bigint float boolean char 长度都是固定的。而数据存储又是紧挨着的,所以怎么样知道哪些数据是一行,哪些数据是哪一个字段的,我们比如表字段和数据是这样的:
那么我们知道bigint占用8字节,int占用4字节,char默认占用1字节,但是对于三个varchar字段却是不知道占用多少字节,所以用一个变长字段长度列表逆序表示字段长度,第一行数据的变长字段长度列表逆序表示:0x04 0x03 0x09, 第二行数据的变长字段长度列表逆序表示:0x04 0x05 0x04。那么这2行数据可以表示为0x04 0x03 0x09 null值列表 头信息 118894019127279619 beautiful men kind 20 F 0x04 0x05 0x04 null值列表 头信息 120095254907979779 good women cool 30 G。
三 Null值列表
在表中,有些字段是允许为null值,如果我们在存储时候,将null存储到磁盘,如果很多null,岂不是很浪费磁盘空间,所以通过位来存储,根据字段数量,决定位的长度,但最少都是8位,如果不够8位,即字段长度不够8,则高位用0补齐。并且null值列表也是逆序排序的。
如果可变长字段也允许null值存在,还需要在变长字段长度列表中存储长度为0吗,这是不需要的,变长字段长度列表只是逆序记录不为空的变长字段长度,那怎么才知道这个字段是不是为空的,根据null值列表就知道了,如果对应的可变长字段不为0,则表示有长度,则从变长字段长度列表获取
以上图为例,总共6个字段,只有2个字段允许为null, 那么第一行就是01,表示倒数的第一个允许为null字段并不是null,倒数第二个允许为null的字段为null,因为至少要8位,则是00000001,同理对应的第二行null值列表00000011,表示这个两个字段都是null.
因为null值列表存在变长字段情况,所以为null的变长字段在变长字段列表中不存在,所以的第一行变长字段长度列表 0x04 0x04 0x03,第二行是0x05 0x05那么整个数据的存储是这样的: 0x04 0x04 0x03 00000001 头信息118894019127279619 men kind code 20 0x05 0x05 00000011 头信息120095254907979779 women great 30
四 头信息
头信息是一个40位长度比特位,存储着一些额外信息,比如当前行是否已经被删除、下一个记录相对位置、字段数量等等。比如:
五 行溢出
我们知道一行数据是放在数据页中的,每一个数据页大小是16KB,如果该行数据超过了16KB,这时候一个数据页存放不下,比如varchar(65535)如果超过65535个字符很可能数据已经超过了16KB,则数据页放不下,这种现象叫做行溢出。常见的容易发生行溢出字段,比如TEXT、BLOB等
怎么解决行溢出呢?
首先:行中的大字段存储一部分数据
然后:同时包含一个20字节的指针指向其他数据页,可能数据页还是放不下,还需要存储到其他数据页,这些数据页最后会构建一个链表,如图示:
六 表空间、段、区和数据页
6.1 数据页
我们知道,数据页存储者数据行,但是数据页只是存储着数据行吗,其实不是的,数据行只是它存储的内容之一,它还有些其他东西,比如文件头,数据页头,最大最小记录,数据行,空闲区域、数据页目录,文件尾部。如图示:
其中文件头占38个字节,数据页头占56字节,最大最小记录占26字节,文件尾部占8个字节,空闲区域和数据页目录大小不确定,刚创建的数据页只有空闲区域,没有数据行。当数据行占据的空闲区域越来越多,则空闲区域越来越少,那么空闲区域写完了,则表示这个页写满了。
6.2 数据区(extent)
一个数据区包含多个数据页,由多个连续的数据页组成,每一个区大小为1M,那么数据页大小16K,那么一个区有64个数据页。
6.3 段(segment)
理论上一个表就是一个段,一个段由多个区组成,一般有数据段、索引段、回滚段等,在MySQL数据即索引,数据段即为B+树叶子结点,索引段即为B+树非叶子节点
6.4 表空间(tablespace)
所有的数据都是存储在表空间的,默认情况下所有数据库共享表空间ibdata1, 即所有数据都在表空间里面,如果启用了参数innodb_file_per_table,则每一个表可以对应一个表空间,但是也只是数据、索引存放到都对表空间,回滚、事务等信息还是在共享表空间中。每一个表空间是由不同的段组成。
MySQL深度剖析之数据在磁盘上存储(2021)相关推荐
- 阿里面试乔戈里被问:MySql数据是如何存储在磁盘上存储的?
关于MySql数据库,相信很多人都不陌生,这是当今最常用的一种关系型数据库,关于MySql的知识也是很丰富的. 那么,不知道大家有没有想过这样的问题:MySql中的数据是存在哪的?又是如何存储的呢? ...
- 数据库原理及应用(索引为什么快,数据在磁盘上如何存储)
引子: 1.数据库有三级模式. 2.物理独立性:数据在磁盘上存储. 3.逻辑独立性:表的逻辑设计. 4.两级映射,表的逻辑不会其物理存储逻辑. 5.视图层:dba给用户展示的部分内容. 一 数据模型 ...
- 一文讲清,MySQL数据库一行数据在磁盘上是怎么存储的?
数据库给使用者最直观的感觉,就是库.表.行.字段,这些概念都是逻辑上的.前面我们深入讲解了Buffer Pool的内部原理,它的基本存储单位是默认大小为16K的页.每页都保存了一行一行的数据.我们按照 ...
- 带你深度剖析《数据在内存中的存储》——C语言
文章目录 一.数据类型介绍 二.整型在内存中的存储方式 2.1 原码.反码.补码的讲解 2.2 大小端介绍 2.2.1 大小端的概念 2.2.2 为什么要区分大小端存储呢? 2.2.3 大小端判断练习 ...
- MySQL深度剖析之索引专题(2021)
9.1 为什么需要使用索引 第一:减少了MySQL需要扫描的数据量,尤其是全表扫描 第二:随机IO变成顺序IO,提升查询速度 可以快速匹配where子句.排序和分组也可以使用索引,匹配原则最左匹配.特 ...
- MySQL深度剖析之Buffer Pool专题(2021)
一 为什么需要Buffer Pool 如果我们每一次查询或者更新都需要到磁盘找到对应数据页,每次的都需要从磁盘加载,那么性能必定是很差的.所以将一些从磁盘加载的数据页,放入到内存缓存起来,而不用每次都 ...
- MySQL深度剖析之undo log redo log binlog专题(2021)
因为每次对磁盘随机读写影响性能,尤其是高并发的时候,所以引入了Buffer Pool, 即只要更新Buffer Pool中的记录,则算更新成功,那如果更新完了还没有flush到磁盘则宕机了,此时内存的 ...
- MySQL深度剖析之SQL语句更新流程(2021)
#1 线程开始执行SQL更新请求之前,会创建事务,并且为当前线程分配一块内存空间叫做binlog cache 注意:binlog cache 是每一个线程分配一个:binlog cache大小受bin ...
- 文件系统,你有想过怎么访问磁盘上存储的数据吗
文件系统示意图: 可以看到,这种数据结构是基于数组和链表的组合,是典型的树形结构. 想要加载某个存在于磁盘上的文件,比如想查找[G:\pic\学习截图\文件系统示意图.png],文件系统查找应用就会以 ...
最新文章
- 免费报名 | 机器学习的第二次入门(入群有福利)
- 提高 GPU 训练利用率的Tricks
- Apache 基金会发布2018财年年报:Java 项目占大半
- Razor视图引擎浅析
- 前端学习(975):bootstrap轮播图
- 从C语言到C++的进阶之C++的非类新特性(篇三)
- 【报告分享】2019年用户生命周期运营白皮书(京东尼尔森出品).pdf(附下载链接)
- linux如何杀死ping进程,linux下ping命令使用详解
- java计算-5%3_JAVA基础教程day03--运算符
- NOIP2017普及组T3(棋盘)题解
- 昂达平板不能开机刷机_常用的昂达平板电脑怎么刷机 常用的昂达平板电脑刷机教程...
- oracle awr 定期,Oracle 每天自动生成AWR报告
- C# “配置系统未能初始化”
- Unity使用Animator.CrossFade后,脚本的OnExitState函数还执行吗
- 前端加速必备之BootCDN
- 《大话物联网(第2版)》赠书活动名单公告
- Android 调用系统裁剪,适配11和12及手机
- win10系统如何清理c盘垃圾
- 基于arduino的一位数码管控制
- java实训心得感想30字_java实训心得体会范文
热门文章
- java testng 项目_java – Junit4和TestNG在Maven的一个项目中
- Anaconda3+Python3.6搭建Tensorflow
- Java高全级别灰色_想问下用过JAVACV的大兄弟,为啥我这边抽取图片总是有灰色图片...
- 方法range作用于对象worksheet时失败_VB.NET Excel操作类(获取工作簿列表和工作表列表及工作表对象)...
- php里的header,PHP中常用的header头部定义有哪些
- Java 算法 单词接龙
- DevEco Studio的下载
- pytorch构造IterableDataset,流式读取文件夹,文件夹下所有大数据文件,逐个文件!逐行读取!(pytorch Data学习四)
- php实现ssh客户端,php无阻塞SSH客户端实例
- mysql视图_MySQL视图详解