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

news2024/11/22 15:29:58

一. 前言

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

变长字段的长度列表,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.coloradmin.cn/o/1647017.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

21_Scala集合_可变数组ArrayBuffer

文章目录 ArrayBuffer1.创建可变数组ArrayBuffer2.增加数据3.删除数据4.修改数据5.查询数据Appendix ArrayBuffer ArrayBuffer可变数组–感觉优点类似于Java的ArrayList 1.创建可变数组ArrayBuffer –请注意下面的mutable import scala.collection.mutable.ArrayBuffer //m…

在Linux上使用Selenium驱动Chrome浏览器无头模式

大家好,我们平时在做UI自动化测试的时候,经常会用到Chrome浏览器的无头模式(无界面模式),并且将测试代码部署到Linux系统中执行,或者平时我们写个爬虫爬取网站的数据也会使用到,接下来和大家分享…

前端框架 Vue 主要用来做什么的?

Vue.js 是一个流行的前端框架,主要用于构建交互式的用户界面。它的设计目标是通过简单的 API 提供高效的数据驱动视图层。Vue 具有响应式数据绑定和组件化的特性,使得开发者可以轻松地构建复杂的单页面应用 (SPA) 和动态网页。 1. 数据驱动视图 Vue 的…

IIS部署vue项目 IIS重写URL

【第一步】安装IIS {1)打开控制面板 -> 打开程序和功能 -> 打开启用或关闭windows功能 (2)找到 Internet Information Services 勾选【web管理工具】和【万维网服务】,然后 确定 【第二步】安装URL重写模块 1). 安装URL …

企业微信hook接口协议,ipad协议http,设置是否自动同意

设置是否自动同意 参数名必选类型说明uuid是String每个实例的唯一标识,根据uuid操作具体企业微信 请求示例 {"uuid":"bc4800492083fdec4c1a7e5c94","state":1 //1 是需要验证同意(需要手动点击同意) 0关闭验证…

下一代自动化,国外厂商如何通过生成性AI重塑RPA?

企业自动化的未来趋势是什么?科技巨头们普遍认为,由生成性AI驱动的AI Agent将成为下一个重大发展方向。尽管“AI Agent”这一术语尚无统一定义,但它通常指的是那些能够根据指令通过模拟人类互动,在软件和网络平台上执行复杂任务的…

Skywalking的重要功能详解

学习本篇文章之前首先要了解一下Sky walking的基础知识 分布式链路追踪工具Sky walking详解 一&#xff0c;Sky walking监控数据库 在admin服务中&#xff0c;连接数据库查询user表中所有数据 引入依赖 <dependency><groupId>mysql</groupId><artifactI…

分享几个.NET开源的AI和LLM相关项目框架

前言 现如今人工智能&#xff08;AI&#xff09;技术的发展可谓是如火如荼&#xff0c;它们在各个领域都展现出了巨大的潜力和影响力。今天大姚给大家分享4个.NET开源的AI和LLM相关的项目框架&#xff0c;希望能为大家提供一些参考。如果你有更好的推荐&#xff0c;欢迎RP投稿或…

YOLOv5入门(四)训练自己的目标检测模型

前言 通过前面几篇文章&#xff0c;已经完成数据集制作和环境配置&#xff08;服务器&#xff09;&#xff0c;接下来将继续实践如何开始训练自己数据集~ 往期回顾 YOLOv5入门&#xff08;一&#xff09;利用Labelimg标注自己数据集 YOLOv5入门&#xff08;二&#xff09;处…

Oceanbase all-in-one单机版部署,通过MySQL客户端连接OB租户,DBEAVER 客户端连接MySQL租户。

一.Oceanbase all-in-one单机版部署 1.修改资源限制。 vim /etc/security/limits.conf root soft nofile 655350 root hard nofile 655350 * soft nofile 655350 * hard nofile 655350 * soft stack unlimited * hard stack unlimited * soft nproc 655360 * hard nproc 6553…

webstorm 常用插件

安装插件步骤&#xff1a; 打开软件&#xff0c;文件 -- 设置-- 插件 -- 输入插件名称 -- 安装 代码截图: code screenShots 先选中代码&#xff0c;按 ctrl shift alt a&#xff0c;就可截取选中的代码颜色注释: comments highlighter 对注释的文字改变颜色高亮成对符号: h…

RK3568 学习笔记 : 精简 u-boot env 默认复杂的多种引导启动设置

前言 环境&#xff1a; 正点原子 Atompi-CA1 RK3568 开发板、正点原子 DLRK3568 开发板&#xff0c;&#xff08;一时脑热买了两块 RK3568 开发板&#xff09;&#xff0c;Atompi-CA1 RK3568 开发板比较小巧&#xff0c;利于一些前期的嵌入式 Linux 开发学习与实践。 RK3568 开…

分享5款PDF编辑软件

PDF编辑不易&#xff0c;有需要的朋友可以试试这5款专业软件&#xff0c;每一个都能直接在PDF文件上编辑&#xff0c;不同的软件对PDF可编辑的范围不同&#xff0c;大家可以按需求选用。 1.edge浏览器 Edge浏览器不仅是浏览网页的得力助手&#xff0c;还悄然成为了轻量级PDF管…

【强训笔记】day11

NO.1 思路&#xff1a;枚举&#xff0c;设一号大礼包的数量为x&#xff0c;二号大礼包的数量为y&#xff0c;用循环枚举一号大礼包的个数得到二号大礼包的数量&#xff0c;使得某一时刻axby的值最大。 代码实现&#xff1a; #include<iostream>using namespace std;lo…

财务世界中数据叙事对于企业决策的影响力

数据叙事是财务规划与分析中一项能够改变企业管理规则、体现数据差异化的技能。它使得财务专业人士能够在企业高层的决策桌上获得一席之地。财务团队可以利用这项出色且无与伦比的技能将数据转化为可操作的业务建议。在当今这个数字化时代&#xff0c;任何值得分享的见解都可以…

在.NET架构的Winform项目中引入“异步编程”思想和技术

在.NET架构的Winform项目中引入“异步编程”思想和技术 一、异步编程引入&#xff08;1&#xff09;异步编程引入背景&#xff08;2&#xff09;异步编程程序控制流图&#xff08;3&#xff09;异步编程前置知识&#xff1a; 二、异步编程demo步骤1&#xff1a;步骤2&#xff1…

『FPGA通信接口』DDR(4)DDR3内存条SODIMMs读写测试

文章目录 前言1.MIG IP核配置2.测试程序3.DDR应用4.传送门 前言 不论是DDR3颗粒还是DDR3内存条&#xff0c;xilinx都是通过MIG IP核实现FPGA与DDR的读写。本文区别于DDR颗粒&#xff0c;记录几个与颗粒配置不同的地方。关于DDR的原理与MIG IP的简介&#xff0c;请查看前面文章&…

商务分析方法与工具(三):Python的趣味快捷-循环控制结构解决随机摇奖

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

Debian 12 Bookworm Linux安装 NVIDIA驱动程序

运行带有 Nvidia 显卡的 Debian 12 Linux 台式机或笔记本电脑的用户将需要 Nvidia 驱动程序才能利用显卡的强大功能来执行游戏、3D 渲染、视频编辑和其他图形密集型任务。 因此&#xff0c;如果你不知道如何在 Debian Linux 上安装 NVIDIA GPU 驱动程序&#xff0c;请按照本教…

从零开始学习生成树实验:一步一步走向精通

大家好&#xff0c;这里是G-LAB IT实验室。 ⭕5月18日 CCNAHCIA 新开班来啦&#x1f44f; 现在报名有早鸟价&#xff0c;感兴趣的可咨询 &#x1f447;&#x1f447;&#x1f447; 敲重点! 可小窗客服咨询课程价格 本课程包含线下面授、线上直播、录播、实验、考试习题、…