Mysql的数据存储

news2024/11/28 0:43:53

Mysql的数据存储

对于mysql而言,数据是存储在文件系统中的,不同的存储存储引擎会有不同的文件格式和组织形式

1、InnoDB数据存储

InnoDB存储格式由大到小:表空间 → 段 → 区 → 页 → 行

对于innodb而言,数据是存储在表空间(文件空间file space)内的,表空间是一个抽象的概念,他对应着硬盘上的一个或多个文件,如下图:

在这里插入图片描述

表空间存储数据的单位是【页】,我们可以这样类比,一个表空间就是个大大的本子,本子里是一页页的数据(innodb是以页为单位进行数据存储的),常用页面类型有很多,不同类型的页面可以存放【不同类型的数据】,这里不展开讲解,暂时统称为【数据页】、他的通用部分如下,每一页大概占用16k的空间:
在这里插入图片描述

  • file header:记录页面的一些通用信息,比如当前页的校验和、页号、上页号、下页号、所属表空间等。
  • file trailer:主要的工作是检验页是否完整。
  • 表空间中的每一个页,都有一个页号(File_PAGE_OFFSET),我们可以通过这个页号在表空间快速定位到指定的页面。这个页号由4个字节组成,也就是32位,所有最多能存放2的32次方页,如果按照一页16k计算,一个表空间最大支持【64TB】的数据。整体的排列中页是连续的,但是页有上下指针,不连续的页也能组成链表。

表空间的示意图如下:

在这里插入图片描述

表空间可以分为系统表空间、独立表空间等:

(1)系统表空间(The System Tablespace)

  • 系统表空间包含了很多【公共数据】,比如InnoDB的数据字典,回滚信息、系统事物信息、二次写缓冲等,老版本的mysql表中的数据也会存储在系统表空间。
  • 系统表空间是一个共享的表空间因为它是被多个表共享的。
  • 该空间的数据文件通过参数【innodb_data_file_path】控制,默认值是ibdata1:12M:autoextend(文件名为ibdata1、12MB、自动扩展)。
  • 当然系统表空间也可以通过配置,修改文件的名称和个数。文件如下图:

在这里插入图片描述

相关变量的设置:

-- 如果1代表开启,0代表关闭
show variables like'innodb_file_per_table'
-- 设置对应的变量
set global innodb_file_per_table=0;
-- 查看系统表空间的配置
show variables like "innodb_data_file_path";
-- 配置文件的配置
innodb_data_file_path=data1:512M;data2:512M:autoextend

(2)独立表空间(File-Per-Table Tablespaces)

  • 独立表空间是默认开启的,在5.6.6以后,Innodb不在默认将各个表的数据存储在【系统表空间】当中,而是会为每一个表建立一个独立表空间,innodb存储引擎的独立表空间为【.ibd】文件。
  • 如果启用了【innodb_file_per_table】参数,需要注意的是每张表的表空间内存放的只是【数据】、【索引】和【插入缓冲Bitmap页】,其他数据如:回滚信息、系统事物信息、二次写缓冲(Double write buffer)等还是放在原来的系统表空间内。
  • 同时说明了一个问题:即使启用了【innodb_file_per_table】参数,系统表空间还是会不断的增加其大小的。

在这里插入图片描述

(3)其他类型的表空间

除了以上两种表空间,,innodb还提供了很多其他类型的表空间,比如通用表空间,undolog表空间、临时表空间等,这里不在赘述。

**tips:**MyIsam数据存储

MyIsam没有表空间的概念,他会在目录中产生2个文件【.MYD】(数据文件)、【 .MYI】(索引文件)三个文件。

在这里插入图片描述

**注意:**在5.7以前【数据文件】和【表信息文件】是分开的,相互独立的。会多一个【.frm】文件,8.0之后进行了合并。

2、组织结构

  • 区(extent)::每一个表空间保存了大量的页,为了更好的管理这些页面,Innodb提出了【区】的概念,对于16k的页,连续64个页就是一个区,大概1M的空间,每一个表空间都是由若干个连续的区组成的,每256个区被划分为一组。
  • 段(Segment):分为索引段,数据段,回滚段等后边会将,段是为了区分不同的数据类型,相同的段存的数据类型是一致的。一个段包含256个区(256M大小)。

inndb表空间结构如下图所示:

在这里插入图片描述

3、Row Format(行记录格式)

  • 一个表的【行记录格式】决定表中行的【物理存储模式】,决定了【DQL】和【DML】的操作性能。越多的行被匹配进独立的磁盘页,sql的性能会更好一些,需要的缓存及io操作就越少。
  • 一条完整的信息记录分为:【记录的额外信息】和【记录的真实数据】两大部分,就如同一箱苹果里的苹果分为包装和苹果一样。
  • 我们可以通过命令SHOW TABLE STATUS LIKE 'table_name'来查看当前表使用的行格式,其中row_format就代表了当前使用的行记录结构类型。

指定行格式的语法如下:

-- 创建数据表时,显示指定行格式
CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名称;
-- 创建数据表时,修改行格式
ALTER TABLE 表名 ROW_FORMAT=行格式名称;

-- 具体如下:
CREATE TABLE `ydl_user`  (
  `user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID'`user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户账号'....
  PRIMARY KEY (`user_id`) USING BTREE
) ROW_FORMAT = DYNAMIC;

2.1、COMPACT行记录格式

【compact行记录】是在MySQL 5.0时被引入的,其设计目标是能高效存放数据。Compact行记录以如下方式进行存储:

在这里插入图片描述

  1. 【变长字段长度列表】:第一个部分是一个非NULL【变长字段长度列表】。这个其实很好理解,我们的数据类型除了定长的char、int还有不定长的如varchar、text等,变长列的真实长度就保存在这个部分,他是按照列的顺序【逆序放置】的。当列的长度小于255字节,如(varchar(50)),用1字节表示;若大于255个字节(varchar(600)),用2个字节表示,这其实也就说明了为什么varchar的最大长度是65536
  2. 【NULL标志位】:第二个部分是【NULL标志位】,他指示了当前行数据中哪些为null值,用一个bitmap表示。举一个例子:假如该标志位为06(二进制:00000110)则表示第二三列(可以为空的列)的数据为NULL。需要注意的是,NULL值标志位仅仅针对可以为【NULL的字段】,如果某个字段被定义为not null,那么这个字段就不会进入NULL值标志位的BitMap中,这样可以节省很多空间,NULL值标志位也是逆序排列,占用空间按照字节数高位补零,如有九个字段可以为空(00000001 01010101)。
  3. 【记录头信息】:第三部分为记录头信息(record header),固定占用5个字节(40位),每位的含义见下表:

在这里插入图片描述

  • 【列的数据信息】:第四部分就是实际存储的每个列的数据了,需要特别注意的是,NULL不占该部分任何数据,即NULL除了占有NULL标志位,实际存储不占有任何空间。Innodb存储变长列(VARCHAR, VARBINARY, BLOB, TEXT)的前768字节,剩下的部分存储在溢出页中。固定长度列,超过768字节的视为变长列。内部存储前768字节,20字节指针存储列的溢出页的地址,所以长度为768+20字节

  • 【事务ID列】:6个字节

  • 【回滚指针列】:7个字节

  • 【RowID列】:若InnoDB表没有定义Primary Key,每行还会增加一个【6字节的RowID列】

在这里插入图片描述

例子:我们不妨举一个例子,看看硬盘的存储格式,以下表为准:

create table test (
  t1 varchar(10),
  t2 varchar(10),
  t3 char(10),
  t4 varchar(10)
) engine=innodb row_format=compact;

insert into row_test values('a''bb''bb''ccc'); 
#改行的长度计算:
-- 【变长字段长度列表】:有3个varchar即可变长度:3列的数据分别长度为2 2 3,用3个字节表示3个varchar的长度----3
-- 【空标志位】:其中4个字段可以为空,使用一个bitmap表示即可,1个字节----1
-- 【记录头信息】:固定长度5个字节----5
-- 【列数据信息】:1+2+2+3=8字节---8
-- 【事务ID】:6个字节----6
-- 【回滚指针】:7个字节----7
-- 【RowID列】:该表没有主键,会生成一个rowid,长度位6字节
-- 【总长度】:3+1+5+8+6+7+6=36个字节长度

节选对应的【真实的表空间】中的的二进制结构表示:

                         03 02 01 00 00 00 10 00 
2c 00 00 00 00 2b 68 00  00 00 00 06 05 80 00 00 
00 32 01 10 61 62 62 62  62 20 20 20 20 20 20 20 
20 63 63 63 03 02 01 00  00 00 18 00 2b 00 00 00  
00 02 01 00 00 00 00 0f  62 c9 00 00 01 b2 01 10  
64 65 65 65 65 20 20 20  20 20 20 20 20 66 66 66  
03 01 06 00 00 20 ff 98  00 00 00 00 02 02 00 00 
00 00 0f 67 cc 00 00 01  b6 01 10 64 66 66 66 

第一行整理如下,需要注意,我们有三个变长列varchar:

03 02 01 // 变长字段长度列表,逆序,t4列长度为3,t2列长度为2,t1列长度为1
00 // NULL标志位,第一行没有NULL值
00 00 10 00 2c // 记录头信息,固定5字节长度
00 00 00 00 2b 68 // RowID我们建的表没有主键,因此会有RowID,固定6字节长度
00 00 00 00 06 05 // 事务ID,固定6个字节
80 00 00 00 32 01 10 // 回滚指针,固定7个字节
61 // 61是16进制,转行为2进制为0110 0001对应10进制为64+32+1=96对应ascii码为'a'
62 62 // 数据'bb'
62 62 20 20 20 20 20 20 20 20 // t3数据'bb'  Ox20十进制是32对应ascii码是空字符
63 63 63 // 数据'ccc'

2.2、REDUNDANT

【Redundant】是MySQL 5.0版本之前InnoDB的行记录存储方式。Redundant行记录以如下方式存储:

在这里插入图片描述

从上图可以看到,Redundant行格式如下:

  1. 第一个部分保存了【字段长度偏移列表】,这个部分保存了该行数据所有列,包括隐藏列的长度偏移量。举一个例子说明一下偏移,假如第一个字段长度为x,第二个字段长度为y,那么列表中第一个字段就是x,第二个字段就是x+y。这个偏移列表是按照列的顺序【逆序排列】。

  2. 第二个部分为记录头信息【record header】,Redundant行格式固定占用6个字节(48位),每位的含义如下图:

    有几个标志位我们可以注意一下,n_fields值代表一行中列的数量,占用10位,这也很好地解释了为什么MySQL【一个行支持最多的列为1023】。

在这里插入图片描述

​ 3.第三个部分就是实际存储的每个列的数据了。

null值的存储,在【字段长度列表】的每个字段长度最高位标记 1 表示这个字段为 NULL。

  • 对于一字节存储,通过【最高位标记字段】判断是否为 NULL,如果为 NULL,则最高位为1,否则为0。剩下的 7 位用来存储数据,所以最多是127。
  • 对于两字节存储,通过【最高位标记字段】判断是否为 NULL,第二位标记这条记录是否在同一页,如果在则为0,如果不在则为1,这其实就涉及到了后面要说的溢出页。剩下的 14 位表示长度,所以最多是16383。
  • 在这种类型的行格式中,无论字段是否为 NULL,或者长度是多少,char(M) 都会占用 M * 字节编码最大长度那么多字节。为 NULL 的话,填充的是 0x00,不为 NULL,长度不够的情况下,末尾补充 0x20。 对于varchar来说,NULL 还是不占用空间的。

小结:

compact格式比redundant存储空间大约减少20%。如果受限于cache命中和磁盘速度,compact格式会快一些,若受限于CPU速度,compact格式会慢一些。

2.3、DYNAMIC

InnoDB Plugin引入了两种新的文件格式(file format,可以理解为新的页格式),对于以前支持的Compact和Redundant格式将其称为Antelope文件格式,新的文件格式称为Barracuda。Barracuda文件格式下拥有两种新的行记录格式Compressed和Dynamic两种。

新的两种格式对于存放BLOB的数据采用了完全的行溢出的方式,在数据页中只存放20个字节的指针,实际的数据都存放在BLOB Page中,而之前的Compact和Redundant两种格式会存放768个前缀字节。mysql8.0默认此格式。

在这里插入图片描述

2.4、COMPRESSED

种新的行记录格式Compressed和Dynamic两种。

新的两种格式对于存放BLOB的数据采用了完全的行溢出的方式,在数据页中只存放20个字节的指针,实际的数据都存放在BLOB Page中,而之前的Compact和Redundant两种格式会存放768个前缀字节。mysql8.0默认此格式。

[外链图片转存中…(img-yj8x7jNh-1678451700006)]

2.4、COMPRESSED

基于dynamic格式,支持表和索引数据压缩。compressed行格式采用dynamic相同的页外存储细节,同时,存储在其中的行数据会以zlib的算法进行压缩,因此对于BLOB、TEXT、VARCHAR这类大长度类型的数据能进行非常有效的存储

在这里插入图片描述
在这里插入图片描述

博客地址:https://bluebeastmight.github.io/

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

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

相关文章

linux系统整理一些工作中常用关于用户,用户组以及文件权限操作的相关命令

文章目录问题:前言:用户和用户组概念前言一、用户前言二、用户组一、添加用户和用户组二、查看用户所属组命令、三、管理用户组方法一、gpasswd命令方式二、newgrp命令方式三、usermod命令用户组实战:赋予用户root权限四、文件修改权限命令ch…

数字孪生与 UWB 技术创新融合:从单点测量到全局智能化

人员定位是指利用各种定位技术对人员在特定场所的位置进行准确定位的技术。人员定位技术主要应用于需要实时监控、管理和保障人员安全的场所,如大型厂区、仓库、医院、学校、商场等。人员定位技术的应用范围非常广泛,例如:-在工厂生产线上&am…

服务器Nginx安装实战

因为Vue项目发布在Tomcat中出现跨域为,所以需要Nginx进行反向代理,所以特此在云服务器中安装Nginx,本文章记录安装过程及解决安装过程中的错误处理。 一、Nginx 安装 登录服务器后,执行命令 yum info gcc-c pcre pcre-devel zl…

keras lstm

keras lstm的参数(1)units:LSTM层的单元个数,即LSTM网络中隐藏节点的数量。(2)activation:激活函数,用于更新内部状态的函数(即门的决策函数)。(3…

dotConnect Universal 4.0.134 Crack

dotConnect Universal 能够呈现和访问不同于Microsoft 和框架的数据库的信息。网。它能够支持大多数数据库服务器以及 Microsoft Access、Oracle、MySQL、DB2、PostgreSQL、SQLite、InterBase、FireBird,最后是 Microsoft SQL Server。它可以通过 ODBC、OLE DB、ADO…

我来跟你讲vue进阶

一、组件(重点) 组件(Component)是 Vue.js 最强大的功能之一。 组件可以扩展 HTML 元素,封装可重用的代码。 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象…

ThreadLocal 的简单使用并深扒其实现原理

在多线程环境下, 如果想要保证每个线程都能独立于其它线程独自运行, 可以使用 ThreadLocal 来解决; ThreadLocal 就是用于提供线程局部变量的一个工具, 也就是说 ThreadLocal 可以为每个线程创建一个单独的变量副本; 其概念与同步机制正好相反, 同步机制是保证多线程环境下数据…

elasticSearch写入原理

elasticSearch写入原理 最近学习完了es相关的课程整理除了es的核心内容,学习这东西知其然知其所以然,自己按照自己的理解整理了es相关的面试题。先热个身,整理一下es的写入原理,有不对的地方请大家指正。 这些原理的东西我觉得还是…

MySql数据库(进阶篇)

👌 棒棒有言:人生总是在前行,不论走到哪里,只要带着信念往前走,比别人多一点努力,你就会多一份成绩;比别人多一点志气,你就会多一份出息;比别人多一点坚持,你…

js学习3(数组)

目录 结构图 数组操作 每日一练 结构图 数组操作 ## 数组中可以存储任何类型元素 ## 创建: 字面量([...])、创建对象(new Array(arr_len)) ## 遍历: 循环遍历、forEach(callback)、map(callback)、filter(callback)、every(callback)、some(callback)、…

1637_fgets函数的功能

全部学习汇总: GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 没想到分析一个函数的实现会这么麻烦,中间利用的一系列的库函数以及内核接口我全都不熟悉。但是,这次的这个函数应该是之前C语言的基本教程…

vscode下载与使用

1.vscode下载 官网下载地址:Download Visual Studio Code - Mac, Linux, Windows下载太慢,推荐文章:解决VsCode下载慢问题_vscode下载太慢_迷小圈的博客-CSDN博客下载太慢,推荐下载链接:https://vscode.cdn.azure.cn/s…

JavaScript Array(数组)对象

数组对象的作用是:使用单独的变量名来存储一系列的值。参数参数 size 是期望的数组元素个数。返回的数组,length 字段将被设为 size 的值。参数 element ...; elementn 是参数列表。当使用这些参数来调用构造函数 Array() 时,新创建的数组的元…

SEO技术风口来了|SEO能否抓住全球约93%的网络用户?

开篇词作者/出品人 | 美洽 SEO 流量专家 白桦为什么要做一个 SEO 专栏?在一部分人眼中,SEO(搜索引擎优化)已经是老掉牙的玩意儿,在这个信息爆炸的年代,它似乎已经无法承担吸引流量的主要作用。但&#xff…

2023年3月北京/广州/杭州/深圳数据治理工程师认证DAMA-CDGA/CDGP

DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业发展里程碑及发展阶梯定义,帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力,促进开展工作实践应用及实际问题解决,形成企业所需的新数字经济下的核心职业…

代码随想录算法训练营第二十四天 | 理论基础、 77. 组合

打卡24天,今天学第七章回溯算法,之前已经学过一遍,现在学第二遍,加油。 今日任务 理论基础77.组合 理论基础 什么是回溯 递归的副产物,有递归就会有回溯 红色的箭头就是回溯 回溯的效率 回溯的本质是穷举&#xff…

ROS通信机制

参考: bilibiliAutolabor官方 回调函数:! 由外部中断激发而执行的函数,函数执行的时间不由函数本身控制,而是由外部激发 1、话题通信 ​ publisher发布者,和subscriber订阅者通过topic相互连接&#xf…

设计模式5——自定义Spring框架

1、Spring核心功能结构 Spring大约有20个模块,由1300多个不同的文件构成。这些模块可以分为:核心容器、AOP和设备支持、数据访问与集成、Web组件、通信报文和集成测试等。下面是Spring框架的整体架构图: 核心容器由beans、core、context 和 …

Vue脚手架的安装(保姆级教程)

Vue脚手架的安装(保姆级教程) 文章目录Vue脚手架的安装(保姆级教程)1.下载vscode2.node下载5.Vue脚手架的安装6.创建Vue项目7.项目的运行1.下载vscode vscode下载地址 2.node下载 node下载 1.打开cmd node -vnpm -v2.在node的…

linux入门---vim的配置

这里写目录标题预备知识如何配置vimvim一键配置预备知识 在配置vim之前大家首先得知道一件事就是vim的配置是一人一份的,每个用户配置的vim都是自己的vim,不会影响到其他人,比如说用户xbb配置的vim是不会影响到用户wj的,虽然不同…