Mysql数据存储格式分析

一、整体存储逻辑

1.1 Mysql数据存放位置

不同的存储引擎,对Mysql数据的存储是不同的。新建一个test数据库,里面有t1,t2和test5三张表,以Innodb和Myisam存储引擎为例:
在这里插入图片描述
Innodb存储引擎:

.frm文件:与表相关的元数据信息都存放在frm文件中,包括表结构的定义信息。
.ibd文件或.ibdata文件:都是存放InnoDB数据的文件【数据和索引】。
【独享表空间存储方式】使用.ibd文件,并且每一个表一个.ibd文件;
【共享表空间存储方式】使用.ibdata文件,所有表共同使用一个.ibdata文件
独享和共享由innodb_file_per_table字段控制,从5.6版本后,默认为1,即使用独享表的方式

在这里插入图片描述
MyISAM存储引擎:

.frm文件:与表相关的元数据信息都存放在frm文件中,包括表结构的定义信息
MVD(MYData)文件:用于存储MyISAM表的数据
MYI(MYIndex)文件:用于存储MyISAM表的索引相关信息

二、详细存储格式分析

考虑到工作中使用Innodb存储引擎居多,后面讨论以Innodb存储引擎为主。ibd文件又称表空间文件,从逻辑和物理上进行了层次性的划分。主要分为:段Segment,区Extent,页Page以及行Row
表结构
下面对每个结构类型进行介绍:

行Row:表示一条记录,是存储的最小单元;
页Page: 考虑到每次读取一个条记录,需要进行一次IO,效率非常低,因此Innodb是按照为单位进行读取的。默认页的大小为16KB,为了提高读取效率,页中的行记录是连续存储,可以方便顺序IO
区Extent: Innodb存储引擎采用的是B+树来存储的。B+ 树中每一层都是通过双向链表连接起来的,如果是以页为单位来分配存储空间,那么链表中相邻的两个页之间的物理位置并不是连续的,可能离得非常远,那么磁盘查询时就会有大量的随机I/O,随机 I/O 是非常慢的。因此,最好的解决办法就是让链表中相邻的页的物理位置也相邻,这样就可以使用顺序 I/O 了,那么在范围查询(扫描叶子节点)的时候性能就会很高。解决方案:在表中数据量大的时候,为某个索引分配空间的时候就不再按照页为单位分配了,而是按照区(extent)为单位分配。每个区的大小为1MB,对于 16KB 的页来说,连续的 64 个页会被划为一个区,这样就使得链表中相邻的页的物理位置也相邻,就能使用顺序 I/O 了。
段Segment:段是由多个区组成的,两个区之间是逻辑上相邻的,物理上不一定相邻。段分为:数据段,索引段和回滚段

  1. 数据段:存放B+树叶子节点的区集合;
  2. 索引段:存放B+树的非叶子节点的区集合;
  3. 回滚段:存放的是回滚数据的区集合。后续用于MVCC版本控制。

2.1 存储格式分类

系统是不断演进的,因此Mysql的存储格式也在不断优化。主要有以下几种存储格式:

COMPACT行格式:是其它几种格式的基础。处理行溢出时,一部分数据存储在当前页中,多余的部分存储在其它页中,然后记录其它页的内存地址
Redundant行格式:已经不再使用。
Dynamic行格式:目前Mysql5默认使用的方式。基本上和Compact一样,只不过在处理行溢出时,Danamic行格式,直接将数据存储在其他页面,然后指向该页面的内存地址
Compressed行格式:采用压缩算法对页面进行压缩。

2.2 存储格式详解

下面分析的行记录存储格式,是Mysql 的COMPACT格式,Dynamic和Compressed都是一样的。
行记录的整体组成部分

2.2.1 额外信息

变成字段长度列表

变长字符有哪些:varchar,test,blob
是否必需:不一定。若表中没有变长字段,则不会有
【变长字段】占用内存大小:例如varchar(M), 在utf-8编码情况下,每个字符占用N个字节,则占用内存大小为:(M*N)个字节。具体情况要看编码格式,以及编码格式下的每个字符占用情况。
存储【变长字符长度】占用的内存大小为: 1.M*N <=255,则占用1字节;2.M*N > 255,则需要区分字符串实际占用的大小L2.1L <= 127, 则使用1个字节来表示;2.2L > 127, 则使用2个字节来表示.
【注意】:1. 不会超过2个字节,因为一条记录的最多占用内存65535个字节2. 若一行记录中,有多个变长字段,那每个变长字段的长度,按照逆序存放3. 若没有变长字段,则不会有这个变长字段长度列表存在

NULL值列表

Mysql会将字段为null的,进行压缩处理,即若多个字段都为null,为了节省内存空间,会将每个允许存储null的列,对应一个二进制位,按照【逆序】存放。其中1表示该列的值为null0表示不为null。例如:有三个字段可以为null,a,b,c,则存储形式为:c         b           a
00000 0         0           0
因mysql要求,存储null值列表必须为整数个字节,因此,不足8的倍数的情况,前面自动补0,同时每8位表示一个字节
注意:1. 因已经表示了是否存储为null,则在真实数据部分,若字段为null,则不会存储

记录头信息
主要用于描述记录的头信息,由固定的5个字节组成。

名称大小(单位:bit)描述
预留位11没有使用
预留位21没有使用
delete_mask1标记该记录是否被删除
min_rec_mask1B+树的每层非叶子节点中的最小记录都会添加该标记
n_owned4表示当前记录拥有的记录数
heap_no13表示当前记录在记录堆的位置信息
record_type3表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录
next_record16表示下一条记录的相对位置

2.2.2 真实数据

隐藏字段

Mysql会为每条记录,添加一下隐藏列。例如:- db row_id: 不是必须的。占用6个字节,行ID,唯一标识一条记录。详见下面的主键生成策略:- db transction_id: 必须的。占用6个字节,事务ID- db roll pointer: 必须的。占用7个字节,回滚指针【主键生成策略】:
1. 优先使用用户自定义主键
2. 若没有,则选取一个唯一非空字段作为主键
3. 若唯一非空字段也没有,则默认添加一个row_id作为主键

真实数据:
就是业务方自己存储的字段值信息。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【HR】阿里三板斧--20240514

参考https://blog.csdn.net/haydenwang8287/article/details/113541512 头部三板斧 战略能不能落地、文化能不能得到传承、人才能不能得到保障。 头部三板斧适用的核心场景有三个&#xff1a;一是战略不靠谱&#xff1b;二是组织效率低、不聚心&#xff1b;三是人才跟不上。对…

每日一学—K邻算法:在风险传导中的创新应用与实践价值

文章目录 &#x1f4cb; 前言&#x1f3af; K邻算法的实践意义&#x1f3af; 创新应用与案例分析&#x1f525; 参与方式 &#x1f4cb; 前言 在当今工业领域&#xff0c;图思维方式与图数据技术的应用日益广泛&#xff0c;成为图数据探索、挖掘与应用的坚实基础。本文旨在分享…

思科模拟器学习1--Vlan Trunk

实验说明&#xff1a;将三台电脑的vlan 加到一台交换机里面&#xff0c;为了验证什么是虚拟局域网&#xff0c;把一个设备隔成三个空间&#xff0c;三个电脑互相不能通讯&#xff1b;目的是&#xff1a;vlan 1的通讯不可以向vlan 2传送&#xff0c;就是消息传送互不干扰的&…

网络完全精通版

一、目录结构 1.1目的的特点 windows和linux windows中C、D、E盘&#xff0c;每个都是一个根系统【多跟系统】 linux中只有一个根【单根系统】 1.2各个目录存储的内容 /root&#xff1a;linux中挂管理员用户的家目录 /home&#xff1a;linux中挂存储普通用户的家目录的目…

linux系统修改网卡名称

说明&#xff1a; 因操作过程需要停用网卡&#xff0c;导致ssh远程连接不上&#xff0c;需要控制台登录操作。 测试环境&#xff1a; CentOS7.9、8.2虚拟机 Suse15 SP4虚拟机 操作步骤&#xff1a; 方法一&#xff1a; 1、 查看网卡当前名称及状态 ip a2、 将网卡状态从启用…

刷题之最长连续序列

哈希表 class Solution { public:int longestConsecutive(vector<int>& nums) {//set记录并且去重nums中的数unordered_set<int>set;for(int i0;i<nums.size();i){set.insert(nums[i]);}int result0;//遍历所有数for(auto iset.begin();i!set.end();i){//如…

怎样计算Excel一列数值中十位数为5的个数?

有一列数字&#xff0c;可能正数也可能是负数&#xff0c;有可能有小数&#xff0c;要怎么计算这列数字中十位数为5的数量有多少个&#xff1f; 一、按示例情况&#xff0c;数字均为整数 公式如下&#xff1a; SUM(--(MID(A1:A6,LEN(A1:A6)-1,1)"5")) 数组公式&a…

多臂老虎机

多臂老虎机 有n根拉杆的的老虎机&#xff0c;每根拉杆获得奖励(值为1)的概率各不相同。 期望奖励更新 Q k 1 k ∑ i 1 k r i 1 k ( r k ∑ i 1 k − 1 r i ) 1 k ( r k k Q k − 1 − Q k − 1 ) Q k − 1 1 k [ r k − Q k − 1 ] Q_k\frac 1k \sum^{k}_{i1}r_i\\…

机器学习笔记 PostgresML教程:使用SQL进行机器学习

机器学习的基本做法是将数据转移到模型的环境中进行训练。由于今天的数据库比机器学习模型大好多个数量级,所以PostgresML的思路是,如果我们将模型引入数据集不是会容易得多吗? PostgresML 是一个建立在流行的 PostgreSQL 数据库之上的综合机器学习平台。它引入了一种称为“…

嵌入式学习-通用定时器

简介 框图介绍 时钟选择 计数器部分 输入捕获和输出比较框图 嵌入式学习全文参考&#xff08;小向是个der&#xff09;做笔记&#xff1a;https://blog.csdn.net/qq_41954556/article/details/129735708

Linux第四节--常见的指令介绍集合(持续更新中)

点赞关注不迷路&#xff01;本节涉及初识Linux第四节&#xff0c;主要为常见的几条指令介绍。 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1f44d;&#x1f3fb; 收藏 ✨ 加关注&#x1f440; 期待与你共同进步! 1. more指令 语法&#xff1a;more [选项][文件]…

r语言数据分析案例-北京市气温预测分析与研究

一、选题背景 近年来&#xff0c;人类大量燃烧煤炭、天然气等含碳燃料导致温室气 体过度排放&#xff0c;大量温室气体强烈吸收地面辐射中的红外线&#xff0c;造 成温室效应不断累积&#xff0c;使得地球温度上升&#xff0c;造成全球气候变暖。 气象温度的预测一直以来都是…