Mysql数据在磁盘上的存储结构

一. 前言

一行数据的存储格式大致如下所示:

变长字段的长度列表,null值列表,数据头,column01的值,column02的值,column0n的值…

二. 变长字段

在MySQL里有一些字段的长度是变长的,是不固定的,比如VARCHAR(255)之类的这种类型的字段,实际上他里面存放的字符串的长度是不固定的,有可能是“hello”这么一个字符串,也可能是“hello word”这么一个字符串。

  • 示例1
格式VARCHAR(10)CHAR(1)CHAR(1)
数据helloaa
存储方式0x05 null值列表 数据头 hello a a
  • 示例2
    多个变长字段, 是逆序存储
格式VARCHAR(10)VARCHAR(5)VARCHAR(20)CHAR(1)CHAR(1)
数据helloa2aa3aa
存储方式0x05 0x02 0x03 null值列表 数据头 hello a a
  • 为什么要逆序存储.
在 MySQL 中,对于变长字段(如 VARCHAR),其长度信息在存储时确实可能以逆序方式存储,这主要涉及到存储格式和性能优化的考量。这个特性尤其在早期版本的 MySQL 中比较明显,而在新版本中,由于存储格式的改进和优化,这种差异可能不那么直观。以下是一些可能导致逆序存储长度信息的原因:### 1. 存储效率在某些场景下,将变长字段的长度信息以逆序方式存储可以提高存储效率。例如,如果一个表包含多个变长字段,MySQL 需要在记录的开始处存储这些字段的长度信息。通过逆序存储这些长度信息,MySQL 可以更有效地处理记录中字段值的增减变化,因为这样做可以减少因字段长度变化而导致的数据移动。### 2. 记录格式MySQL 中,尤其是 InnoDB 存储引擎,采用了多种记录格式(如 COMPACT 和 REDUNDANT)。在某些记录格式中,字段长度的存储方式可能被设计为逆序,部分原因是为了优化记录的解析过程。在解析一条记录时,从记录的末尾开始可以更快地定位到可变长度字段的实际内容,尤其是在需要跳过某些字段以访问特定字段时。### 3. 兼容性和历史原因MySQL 的不同版本和存储引擎在记录格式和存储策略上可能有所不同。一些设计决策,包括字段长度信息的存储方式,可能受到向后兼容性和历史遗留问题的影响。随着 MySQL 版本的发展,存储格式和算法不断优化,但在一些情况下,逆序存储长度信息的方式可能被保留下来,以确保数据的一致性和有效的性能表现。

三.mysql innodb_default_row_format 可以配置那些值, 有什么区别

在MySQL中,innodb_default_row_format选项指定了InnoDB表创建时的默认行格式。这个设置对于新创建的表非常重要,因为它影响了数据的存储方式、空间利用率和性能。innodb_default_row_format可以配置为以下几个值,每个值代表不同的行格式:

可配置的值及其区别

  1. Redundant

    • 这是早期版本的InnoDB行格式,默认使用在MySQL 5.0及更早版本中。
    • 它提供了最基本的特性集合,但在空间利用率和性能方面并不是最优的。
    • Redundant行格式支持较小的最大行大小和较少的数据类型优化。
  2. Compact

    • 从MySQL 5.0版本引入,是一个比Redundant更高效的行格式,旨在改进空间利用率。
    • 它减少了头信息的尺寸,并采用了更高效的方式存储NULL值和可变长度字段。
    • 对于许多应用而言,Compact是一个好的默认选择,因为它提供了较好的空间效率而不牺牲太多性能。
  3. Dynamic

    • 在MySQL 5.7.9及以后版本中,Dynamic成为了默认的行格式。
    • 它解决了Compact格式中一些限制,特别是关于BLOB和TEXT类型字段的更高效存储。在Dynamic格式中,这些类型的字段只在行中存储20字节的指针,实际数据存储在外部页面。
    • Dynamic行格式提供了更好的空间利用率,特别是对于包含大量BLOB或TEXT字段的表。
  4. Compressed

    • Compressed行格式允许对整行数据进行压缩,进一步节省存储空间。
    • 它特别适用于那些磁盘空间成本高昂或者需要存储大量历史数据的环境。
    • 使用Compressed格式可能会对CPU资源产生额外负担,因为需要在读写时进行压缩和解压缩操作。

选择合适的行格式

选择哪种行格式取决于具体的应用需求。DynamicCompressed格式在空间利用率方面提供了显著的优势,特别是对于包含大量长文本或BLOB字段的表。然而,Compressed格式可能会引入一定的性能开销。对于大多数应用,Dynamic行格式提供了一个很好的平衡点,特别是在MySQL 5.7.9及以后版本中,它成为了默认选择。

配置方法

在MySQL中,你可以通过几种方式查询默认的行格式(row format)。默认的行格式是指当你创建一个新表且没有指定行格式时,MySQL所使用的行格式。下面介绍两种常见的方法来查询默认行格式:

    1. 查看全局变量

MySQL允许你通过查询全局系统变量来了解当前的默认行格式。你可以使用以下SQL命令查询默认的行格式:

SHOW VARIABLES LIKE 'innodb_default_row_format';

这条命令会返回innodb_default_row_format变量的值,该值表示InnoDB存储引擎默认使用的行格式。可能的返回值包括RedundantCompactDynamic等。

    1. 查看服务器配置文件

MySQL的默认行格式也可以在服务器的配置文件(通常是my.cnfmy.ini,具体取决于你的操作系统)中进行设置和查看。在配置文件中搜索innodb_default_row_format这一行。例如:

[mysqld]
innodb_default_row_format=dynamic

如果在配置文件中设置了该参数,它将决定默认的行格式。请注意,更改配置文件需要重启MySQL服务器才能生效。

  • 附加信息

  • MySQL版本的影响:不同版本的MySQL可能有不同的默认行格式设置。例如,在MySQL 5.7.9及以后版本中,默认行格式是DYNAMIC

  • 修改默认行格式:你可以通过修改配置文件或设置全局变量的方式来更改默认的行格式,但请注意更改默认行格式可能会影响新创建表的性能和存储效率。

  • 表级行格式设置:即使更改了默认行格式,你仍然可以在创建表时通过ROW_FORMAT选项指定特定表的行格式,这将覆盖全局默认设置。

四. NULL值列表

对所有的NULL值,不通过字符串在磁盘上存储,而是通过二进制的bit位来存储,一行数据里假设有多个字段的值都是NULL,那么这多个字段的NULL,就会以bit位的形式存放在NULL值列表中。

  • 示例
    建表语句
CREATE TABLE customer (name VARCHAR(10) NOT NULL,address VARCHAR(20),gender CHAR(1),job VARCHAR(30),school VARCHAR(50)
) ROW_FORMAT=COMPACT;

上面那个表就是一个假想出来的客户表,里面有5个字段,分别为name、address、genderjob、school,就代表了客户的姓名、地址、性别、工作以及学校。

其中有4个变长字段,还有一个定长字段,然后第一个name字段是声明了NOT NULL的,就是不能为NULL,其他4个字段都可能是NULL的。

存储数据: “jack NULL m NULL xx_school”

  1. 先看变长字段长度列表
    一共有4个变长字段, 变长字段的值是NULL,就不用在变长字段长度列表里存放他的值长度了. 所以在上面那行数据中,只有name和school两个变长字段是有值的,把他们的长度按照逆序放在变长字段长度列表中就可以了

0x09 0x04 NULL值列表 头信息 column1=value1 column2=value2 … columnN=valueN

  1. NULL值列表
    允许值为NULL,不是说一定值就是NULL了,只要是允许你为NULL的字段,在这里每个字段都有一个二进制bit位的值,如果bit值是1说明是NULL,如果bit值是0说明不是NULL。
    比如上面4个字段都允许为NULL,每个人都会有一个bit位,这一行数据的值是“jack NULL m NULL xx_school”,然后其中2个字段是null,2个字段不是null,所以4个bit位应该是:1010
    NULL值列表存放的时候,他一般是8个bit位的倍数,如果不足8个bit位就高位补0

0x09 0x04 00000101 头信息 column1=value1 column2=value2 … columnN=valueN

五. 数据头 (40个bit)

数据头是用来描述这行数据

这40个bit位里,第一个bit位和第二个bit位,都是预留位,是没任何含义的

一个bit位是delete_mask,他标识的是这行数据是否被删除了

1-23 : delete_mask4: min_rec_mask5-9 : n_owned10-23: heap_no24-26: record_type27-40: next_record
预留位是否被删除在B+树里每一层的非叶子节点里的最小值, 用于指示是否有记录具有相同的键值位于它之后, 用于优化记录的读取在B+树索引结构中,一个索引记录(record)“拥有”的相邻记录数当前这行数据在记录堆里的位置这行数据的类型: 0代表的是普通类型,1代表的是B+树非叶子节点,2代表的是最小值数据,3代表的是最大值数据指向他下一条数据的指针

六. 字符串存储(根据字符集编码存储)

表结构:

CREATE TABLE customer (name VARCHAR(10) NOT NULL,address VARCHAR(20),gender CHAR(1),job VARCHAR(30),school VARCHAR(50)
) ROW_FORMAT=COMPACT;

存储数据: jack NULL m NULL xx_school

真实存储类似 (非最终存储结构, 字符串尚未编码):
0x09 0x04 00000101 0000000000000000000010000000000000011001 jack m xx_school

字符串根据数据库指定的字符集编码,进行编码之后再存储的

编码后的格式(非最终存储结构):
0x09 0x04 00000101 0000000000000000000010000000000000011001 616161 636320 6262626262

在实际存储一行数据的时候,会在他的真实数据部分,加入一些隐藏字段

  1. 首先有一个DB_ROW_ID字段,这就是一个行的唯一标识,是他数据库内部的一个标识,不是你的主键ID字段。
    如果没有指定主键和unique key唯一索引的时候,他就内部自动加一个ROW_ID作为主键。

  2. 接着是一个DB_TRX_ID字段,这是跟事务相关的,他是说这是哪个事务更新的数据,这是事务ID

  3. 最后是DB_ROLL_PTR字段,这是回滚指针,是用来进行事务回滚的

实际一行数据存储(最终)
0x09 0x04 00000101 0000000000000000000010000000000000011001 00000000094C(DB_ROW_ID)00000000032D(DB_TRX_ID) EA000010078E(DB_ROL_PTR) 616161 636320 6262626262

七. 行溢出

在MySQL的InnoDB存储引擎中,“行溢出”(Row Overflow)是指一行数据过大,无法完全存储在一个数据库页(Page)中时发生的情况。这通常发生在包含大量文本或二进制数据(如BLOB或TEXT类型字段)的行上。InnoDB的页面大小通常为16KB,当一行数据的总大小超过这个限制时,就会发生行溢出。

  • 为什么会有行溢出?
    InnoDB使用B+树存储机制来组织数据表和索引。每个B+树节点(页)有一个最大的空间限制,默认情况下是16KB。大多数行数据都能完整地存储在单个页内,但当遇到特别大的字段值时,如大文本或BLOB字段,整行数据可能无法适应单个页的空间限制。

  • 行溢出的处理机制:
    当InnoDB遇到一个无法适应单个页的大行时,它采用的策略是将主要的行数据保存在原始页中,但会将大字段的一部分或全部移动到其他页(溢出页)上。原始记录页中的大字段位置会被一个指针替代,这个指针指向存储实际数据的溢出页。

  • 行溢出的影响:

性能影响:访问涉及行溢出的数据可能需要额外的磁盘I/O操作,因为需要读取一个或多个额外的溢出页来获取完整的行数据。这种额外的I/O开销可能会导致性能下降,特别是在大量随机访问的场景中。

空间利用:虽然行溢出机制允许InnoDB表存储大于页面大小的行数据,但这种方式可能导致存储空间的利用率不是很高。溢出页可能不会完全填满,特别是当存储非常大的字段时。

  • 如何管理行溢出:

适当的表设计:尽可能避免在表中使用大量的大型字段。如果应用确实需要存储大量文本或二进制数据,考虑将这些数据分割成较小的部分,或者使用外部存储系统。

选择合适的行格式:对于包含大字段的表,使用DYNAMIC或COMPRESSED行格式可能更合适。这些行格式提供了更高效的行溢出数据管理机制。

监控和优化:使用工具和命令(如SHOW TABLE STATUS)来监控表的大小和行格式,以及定期进行数据库优化,可以帮助管理和减轻行溢出的影响。

八. 数据页

MySQL中进行数据操作的最小单位应该是数据页
执行crud的时候,都会从磁盘上加载数据页到Buffer Pool的缓存页里去,然后更新了缓存页后,又会刷新回磁盘上的数据页里去

数据页拆分成了很多个部分,大体上来说包含了文件头、数据页头、最小记录和最大记录、多个数据行、空闲空间、数据页目录、文件尾部。

  • 数据区域存储占比

其中文件头占据了38个字节,
数据页头占据了56个字节,
最大记录和最小记录占据了26个字节,
数据行区域的大小是不固定的,
空闲区域的大小也是不固定的,
数据页目录的大小也是不固定的,
然后文件尾部占据8个字节。

九. 表空间

表都是有对应的表空间的,每个表空间就是对应了磁盘上的数据文件,在表空间里有很多组数据区,一组数据区是256个数据区,每个数据区包含了64个数据页,是1mb

表空间的第一组数据区的第一个数据区的头三个数据页,都是存放特殊信息的;

表空间的其他组数据区的第一个数据区的头两个数据页,也都是存放特殊信息的

在这里插入图片描述

创建的表,其实都是有一个表空间的概念,在磁盘上都会对应着“表名.ibd”这样的一个磁盘数据文件
在物理层面,表空间就是对应一些磁盘上的数据文件。

有的表空间,比如系统表空间可能对应的是多个磁盘文件,有的我们自己创建的表对应的表空间可能就是对应了一个“表名.ibd”数据文件。

然后在表空间的磁盘文件里,会有很多很多的数据页,

一个表空间里包含的数据页实在是太多了,不便于管理,所以在表空间里又引入了一个数据区的概念,英文就是extent

一个数据区对应着连续的64个数据页,每个数据页是16kb,所以一个数据区是1mb,然后256个数据区被划分为了一组。

对于表空间而言,他的第一组数据区的第一个数据区的前3个数据页,都是固定的,里面存放了一些描述性的数据。比如FSP_HDR这个数据页,他里面就存放了表空间和这一组数据区的一些属性。

IBUF_BITMAP数据页,里面存放的是这一组数据页的所有insert buffer的一些信息。

INODE数据页,这里也是存放了一些特殊的信息

然后这个表空间里的其他各组数据区,每一组数据区的第一个数据区的头两个数据页,都是存放特殊信息的,比如XDES数据页就是用来存放这一组数据区的一些相关属性的,其实就是很多描述这组数据区的东西

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

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

相关文章

设计模式Java实现-工厂模式

✨这里是第七人格的博客✨小七,欢迎您的到来~✨ 🍅系列专栏:设计模式🍅 ✈️本篇内容: 工厂模式✈️ 🍱本篇收录完整代码地址:https://gitee.com/diqirenge/design-pattern 🍱 楔子 记得刚…

Python量化炒股的统计数据图

Python量化炒股的统计数据图 单只股票的收益统计图 查看单只股票的收盘价信息 单击聚宽JoinQuant量化炒股平台中的“策略研究/研究环境”命令,进入Jupyter Notebook的研究平台。然后单击“新建”按钮,创建Python3文件,输入如下代码如下&am…

ComfyUI搭建和注意事项for WIN[笔记]

下载ComfyUI(GitHub - comfyanonymous/ComfyUI: The most powerful and modular stable diffusion GUI, api and backend with a graph/nodes interface.) 从源码上搭建比较麻烦,一般不推荐,所以跑到release里面找一个下载。我的显卡是GeFore GTX 1050 …

STM32编译前置条件配置

本文基于stm32f104系列芯片,记录编程代码前需要的操作: 添加库文件 在ST官网下载标准库STM32F10x_StdPeriph_Lib_V3.5.0,解压后,得到以下界面 启动文件 进入Libraries,然后进入CMSIS,再进入CM3&#xff…

深度学习中的不确定性量化:技术、应用和挑战综述(一)

不确定性量化(UQ)在减少优化和决策过程中的不确定性方面起着关键作用,应用于解决各种现实世界的科学和工程应用。贝叶斯近似和集成学习技术是文献中使用最广泛的两种UQ方法。在这方面,研究人员提出了不同的UQ方法,并测试了它们在各种应用中的…

018、Python+fastapi,第一个Python项目走向第18步:ubuntu24.04 安装cuda和pytorch环境

一、说明 我们安装了pytorch环境之后,会用yolo v9 来测试一下,看8g 显存能不能跑下来,上次用无影云电脑,4cpu8g内存直接爆了,云电脑也死机了,提示一直占用内存不释放,我自己的云电脑不能占用内…

Java中的maven的安装和配置

maven的作用 依赖管理 方便快捷的管理项目依赖的资源,避免版本冲突问题 统一项目管理 提供标准,统一的项目结构 项目构建 标准跨平台(Linux、windows、MacOS)的自动化项目构建方式 maven的安装和配置 在maven官网下载maven Ma…

【革命启示录】Spring框架:Java开发的“核聚变”能量源!

Hello,我是阿佑,今天给大家整的活是 《Java开发的“核聚变”能量源》 文章目录 Spring框架原理详解一、引言简介目的特点例子 二、背景介绍问题解决方案例子 三、核心概念3.1 控制反转(Inversion of Control, IoC)定义实现例子与代…

多商户Docker Supervisor进程管理器部署

Dockerfile 根目录下没有Dockerfile的可以复制下面的命令 # 使用基础镜像 FROM leekay0218/crmeb-mer## 复制代码 ## 在本地调试注释掉,使用映射把文件映射进去 #ADD ./ /var/www# 设置工作目录 WORKDIR /var/www# 设置时区为上海 ENV TZAsia/Shanghai RUN ln -sn…

python安装问题及解决办法(pip不是内部或外部命令也不是可运行)

pip是python的包管理工具,使python可在cmd(命令行窗口,WinR后输入cmd)中执行 针对 “pip不是内部或外部命令也不是可运行” 问题,需要在安装的时候将python添加到环境变量中 上图第三个选项必须勾选才能在cmd中使用pi…

python从0开始学习(四)

目录 前言 1、算数运算符 1.1 //:整除运算符 1.2 %:取模操作 1.3 **:幂运算 2、赋值运算符 3、比较运算符 4、逻辑运算符 5、位运算符 5.1 &:按位与 5.2 |:按位或 5.3 ^:按位异或 5.4 ~:按位取反 5.5…

如何保证Redis双写一致性?

目录 数据不一致问题 数据库和缓存不一致解决方案 1. 先更新缓存,再更新数据 该方案数据不一致的原因 2. 先更新数据库,再更新缓存 3. 先删除缓存,再更新数据库 延时双删 4. 先更新数据库,再删除缓存 该方案数据不一致的…

我独自升级崛起游戏账号登录注册教程 (5.8最新版)

新韩漫公司所发布的这项动作游戏已向玩家们敞开大门,为大家带来了前所未有的游戏体验和乐趣。这个游戏内包含了大量令人着迷的故事、令人印象深刻的战斗场景以及丰富多样的娱乐元素。在这其中最为引人注目的一点就是游戏内容中融入了“虚拟角色”的元素,…

【webrtc】RemoteAudioSource的创建线程

m98 代码&#xff1a;I:\webrtc m98_yjf\src\pc\rtp_transmission_manager.cc RtpTransmissionManager::CreateReceiver 在信令线程创建receiver receiver 是&#xff1a; rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>receiver;其实际…

专家解读 | NIST网络安全框架(1):框架概览

随 着信息技术的快速发展&#xff0c;组织面临着越来越严峻的网络安全挑战。NIST网络安全框架&#xff08;NIST Cybersecurity Framework&#xff0c;CSF&#xff09;是一个灵活的综合性指南&#xff0c;旨在协助各类组织建立、改进和管理网络安全策略&#xff0c;以加强网络安…

【docker 】 push 镜像提示:denied: requested access to the resource is denied

往 Docker Registry &#xff08;私服&#xff09;push 镜像提示&#xff1a;denied: requested access to the resource is denied 镜像push 语法&#xff1a;docker push <registry-host>:<registry-port>/<repository>:<tag> docker push 192.16…

【软件工程】需求分析

目录 前言需求分析需求获取UML概述用例图用例图的组成用例图中的符号和含义包含的两种使用场景 用例图补充&#xff1a;“系统”用例模型建模确定系统参与者确定系统用例 用例文档用例文档组成部分 活动图组成元素初始节点和终点活动节点转换决策与分支、合并分岔与汇合 类图类…

将文本中的unicode字符替换成汉字

背景介绍 msql workbench导出数据库表的数据 导出的json数据 [{"english_id":1, "english_word":"ambition", "homophonic":"am-\u4ffa\uff0cbi-\u5fc5,tion-\u80dc\uff1a\u4ffa\u5fc5\u80dc", "chinese":&quo…

线性表的概念与结构,以及顺序表和链表的简单概念

1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线…

华为 huawei 交换机 配置 MUX VLAN 示例(汇聚层设备)

组网需求 在企业网络中&#xff0c;企业所有员工都可以访问企业的服务器。但对于企业来说&#xff0c;希望企业内部部分员工之间可以互相交流&#xff0c;而部分员工之间是隔离的&#xff0c;不能够互相访问。 如 图 6-4 所示&#xff0c; Switch1 位于网络的汇聚层&#xff0…