MySQL中怎么存放一条记录

news2024/12/27 12:57:03

2.2.1. MySQL中一行记录是怎么存储的?

MySQL的数据存储在那个文件?

每创建一个 database(数据库)都会在 /var/lib/mysql/ 目录里面创建一个以 database 为名的目录,然后保存表结构和表数据的文件都会存放在这个目录里。

在数据库目录中包含三个文件: 

  •  db.opt:存储当前数据库的默认字符集和字符校验规则
    • 表名.ibd:存储表数据,也称为独占表空间文件,每张表都有独立的.ibd文件。
    • 表名.firm:存储表结构,每建立一张表都生成一个.firm文件

表空间文件的结构:

表空间由段(segment)、区(extent)、页(page)、行(row)组成

  1. 行(row)

表中的记录都是按行存放,每行记录根据不同的行格式,有不同的存储结构

  1. 页(page)

InnoDB 的数据是按「页」为单位来读写的,每个页默认空间大小是16kb,是InnoDB 存储引擎磁盘管理的最小单元,常见的有数据页、undo 日志页、溢出页等等,行记录是用数据页管理的。

  1. 区(extent)

B+ 树中每一层都是通过双向链表连接的,以页为单位来分配存储空间,链表中相邻的两个页之间的物理位置并不连续,磁盘查询时就会有大量的随机I/O,随机 I/O 是非常慢的。当表中数据量大时,不再以页为单位给索引分配空间,而是按照区。每个区大小为1MB,连续的64的页会被划分为一个区,使链表中相邻的页的物理位置也相邻,就能使用顺序 I/O 了。

  1. 段(segment)

表空间由各个段组成,段由多个区组成。段一般分为数据段、索引段、和回滚段等。

      • 索引段:存放 B + 树的非叶子节点的区的集合;
      • 数据段:存放 B + 树的叶子节点的区的集合;
      • 回滚段:存放的是回滚数据的区的集合。

InnoDB 行格式有哪些?

行格式(row_format),是一条记录的存储结构。

InnoDB 提供了 4 种行格式,分别是 Redundant、Compact、Dynamic和 Compressed 行格式。

      • Redundant 古老的行格式, MySQL 5.0 版本之前用的行格式,现在基本没人用了。
      • MySQL 5.0 之后引入了 Compact, 是一种紧凑的行格式,为了让一个数据页中可以存放更多的行记录,从 MySQL 5.1 版本之后,行格式默认设置成 Compact。
      • Dynamic 和 Compressed 两个都是紧凑的行格式,它们的行格式都和 Compact 差不多,都是基于 Compact 改进一点东西。从 MySQL5.7 版本之后,默认使用 Dynamic 行格式。

COMPACT 行格式长什么样?

一条完整的记录分为「记录的额外信息」和「记录的真实数据」两个部分。

记录的额外信息:

  1. 变长字段长度列表:

存放记录的真实数据占用的大小,读取时根据「变长字段长度列表」读取对应长度的数据,其他变长字段同理。

用一个实例来进行说明:

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL,
  `name` VARCHAR(20) DEFAULT NULL,
  `phone` VARCHAR(20) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
  -- 字符集是 ascii(所以每一个字符占用的 1 字节)
) ENGINE = InnoDB DEFAULT CHARACTER SET = ascii ROW_FORMAT = COMPACT;

-- 例如,表中有3条记录
+-------------+-------------+-------------------+-------------------+
|  					id| 			 name | 						phone | 							age |
+-------------+-------------+-------------------+-------------------+
|           1 |           a |               123 |                18 |
+-------------+-------------+-------------------+-------------------+
|           2 |          bb |              1234 |              NULL |
+-------------+-------------+-------------------+-------------------+
|           3 |         ccc |              NULL |              NULL |
+-------------+-------------+-------------------+-------------------+
    • 第一条记录:

name字段的值是a,真实数据占用1字节。phone字段的值是123,真实数据占用3字节。age和id不是变长字段。

这些变长字段的真实数据占用的字节数会按照字段的顺序逆序存放。

    • 第三条记录:phone字段是NULL,NULL 不会存放在行格式中记录的真实数据。

为什么「变长字段长度列表」的信息要按照逆序存放?

因为「记录头信息」中指向下一个记录的指针,指向的是下一条记录的「记录头信息」和「真实数据」之间的位置,这样的好处是向左读就是记录头信息,向右读就是真实数据,比较方便。

还可以使位置靠前的 记录的真实数据和数据对应的字段长度信息可以同时在一个 CPU Cache Line 中,这样就可以提高 CPU Cache 的命中率

同样的道理, NULL 值列表的信息也需要逆序存放。

  1. NULL值列表

就是用来存储NULL值的,每个允许NULL值的字段对应一个二进制位,按照字段的顺序逆序排列。二进制位的值是1时,表示该字段是NULL,为0表示不为NULL。NULL值列表必须整数个字节表示,使用的二进制位数不够整个字节,在字节高位补0。

根据三条记录来看NULL值怎么存储的

    • 第一条记录,没有NULL值,用整数字节的二进制位表示NULL,不足8位高位补0。

    • 第二条记录,age字段是NULL,NULL值列表十六进制表示就是0x04。

    • 第三条记录,phone和age字段都是NULL值,NULL值列表十六进制表示就是0x06。

三条记录NULL值列表填充完成后:

每个数据库表的行格式都有「NULL 值列表」吗?

不是,所有字段都是NOT NULL的时候就不会有NULL值列表了,都设置为NOT NULL还能节省至少1字节的存储空间。

  1. 记录头信息

记录头信息中包含的内容很多,列举几个比较重要的:

  • delete_mask :标识此条数据是否被删除。执行 detele 删除记录的时候,并不会真正的删除记录,只是将这个记录的 delete_mask 标记为 1。
  • next_record:下一条记录的位置。记录与记录之间是通过链表组织的。指向的是下一条记录的「记录头信息」和「真实数据」之间的位置。
  • record_type:表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录。

记录的真实数据:

除了自己定义的字段,还有三个隐藏字段,分别为:row_id、trx_id、roll_pointer。

  • row_id:建表的时候指定了主键或者唯一约束列,就没有 row_id 隐藏字段了。如果既没有指定主键,又没有唯一约束, InnoDB 就会为记录添加 row_id 隐藏字段。row_id不是必需的,占用 6 个字节。

  • trx_id:事务id,表示这个数据是由哪个事务生成的。 trx_id是必需的,占用 6 个字节。

  • roll_pointer:记录上一个版本的指针。roll_pointer 是必需的,占用 7 个字节。

VARCHAR()的最大取值范围是多少?

除了 TEXT、BLOB 类型的字段,限制最大为 65535 字节,注意是一行的总长度,不是一列。

要算 varchar(n) 最大能允许存储的字节数,要看数据库表的字符集,不同的字符集,1个字符占用字节不同,比如 ascii 字符集, 1 个字符占用 1 字节, varchar(100) 最大能允许存储 100 字节的数据。

65535个字节中是包含了「变长字段长度列表」和 「NULL 值列表」所占用字节数的,变长字段存储的字节数小于255字节占用1个字节,如果大于255字节占用两个字节。

计算VARCHAR(n)的最大值需要减去「变长字段长度列表」和 「NULL 值列表」所占用的字节数的,

65535-2-1=65532。

在 UTF-8 字符集下,一个字符最多需要三个字节,varchar(n) 的 n 最大取值就是 65532/3 = 21844。

行溢出后,MySQL是怎么处理的?

MySQL 中磁盘和内存交互的基本单位是页,一个页的大小一般是 16KB,也就是 16384字节,一个 varchar(n) 类型的列最多可以存储 65532字节,一些大对象如 TEXT、BLOB 可能存储更多的数据,这时一个页可能就存不了一条记录。这个时候就会发生行溢出,多的数据就会存到另外的「溢出页」中

一个页存不下一条记录,记录的真实数据处存放部分数据,然后有20个字节存放溢出页的地址,剩余部分存到溢出页中。

Compressed 和 Dynamic采用完全溢出方式,有数据溢出时,记录的真实数据处只存放20字节的指针,指向溢出页,真实数据都存放在溢出页中。

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

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

相关文章

透视天气:数据可视化的新视角

数据可视化在天气方面能够为我们带来极大的帮助。天气是人类生活中一个重要的因素,对于农业、交通、航空、能源等各个领域都有着重要的影响。而数据可视化技术通过将复杂的天气数据转化为直观、易懂的图表、图像或地图等形式,为我们提供了更深入、更全面…

Windows系统下安装Mosquitto的步骤(2)

接前一篇文章:Windows系统下安装Mosquitto的步骤(1) 本文内容参考: Windows10上安装Mosquitto的步骤(win10、win11 安装mqtt) - IPS99技术分享 MQTT:windows环境下配置MQTT服务器(mosquitto)_…

第7篇:创建Nios II工程之控制LED<二>

Q:上一期我们完成了Quartus硬件工程部分,本期我们创建Nios II软件工程这部分。 A:创建完BSP和Nios II Application之后,在source文件main.c中添加LED控制代码:system.h头文件包含了Platform Designer系统中IP的硬件信…

复旦 北大 | 从头训练中文大模型:CT-LLM

引言 当前,绝大多数大模型(LLMs)基本上都是以英文语料库训练得到的,然后经过SFT来匹配不同的语种。然而,今天给大家分享的这篇文章旨在从头开始训练中文大模型,在训练过程中「主要纳入中文文本数据」&…

易查分如何使用导出PDF功能?

易查分的导出PDF文件功能可以将查询结果下载到本地,也可用于打印出纸质资料。老师和学生家长都可以自主导出PDF文件,下面就来教大家如何使用此功能。 📌老师如何导出PDF? 在查询管理页,点击管理按钮-导出,可…

完美解决AttributeError: module ‘backend_interagg‘ has no attribute ‘FigureCanvas‘

遇到这种错误通常是因为matplotlib的后端配置问题。在某些环境中,尤其是在某些特定的IDE或Jupyter Notebook环境中,可能会因为后端配置不正确而导致错误。错误信息提示 module backend_interagg has no attribute FigureCanvas 意味着当前matplotlib的后…

经典网络解读——Efficientnet

论文:EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks(2019.5) 作者:Mingxing Tan, Quoc V. Le 链接:https://arxiv.org/abs/1905.11946 代码:https://github.com/tensorflow/t…

自动控制原理学习--平衡小车的控制算法(一)

基于单片机STM32的两轮平衡小车,单片机的各种IO、定时器、通讯等等一大堆要理解、编程,但这些都是琐碎的文档知识,需要花时间看各个模块的接口文档进而编程,需要良好的编程逻辑思维,去获取相关的传感模块信息&#xff…

Instal IIS on Windows Server 2022 Datacenter

和以往版本一样,没有什么不同,So easy! WinR - ServerManager.exe 打开服务器管理器,点击【添加角色和功能】,选择自己想要的角色和功能。 一、开始之前:帮助说明,点击【下一步】;…

鸿蒙原生应用元服务开发-Web加载本地页面

将本地页面文件放在应用的rawfile目录下,开发者可以在Web组件创建的时候指定默认加载的本地页面 ,并且加载完成后可通过调用loadUrl()接口变更当前Web组件的页面。 在下面的示例中展示加载本地页面文件的方法: 将资源文件放置在应用的resou…

Matlab生成txt文件导入到Vivado仿真

Matlab处理数据并将其写入txt文件 %% Txt Generate pre_RS_datadec2bin(simDataIn,8); %将数据转化为8bit的二进制 fidfopen("F:\FPGA\Xilinx_vivado\project\dvbstestbench\dbvs\matlab\pre_RS_data.txt","wt"); for i1:n*nMessages %数据…

网盘—下载文件

本文主要讲解网盘文件操作的下载文件部分,具体步骤如下: 目录 1、实施步骤 2、代码实现 2.1、添加下载文件的协议 2.2、添加下载文件函数 2.3、添加信号槽 2.4、实现槽函数 2.5、设置download状态 2.6、添加定义 2.7、服务器接收数据 2.8、添…

【docker】Docker开启远程访问

将构建的镜像自动上传到服务器。 需要开放 Docker 的端口,让我们在本地能连接上服务器的 Docker,这样,才能上传构建的镜像给 Docker。 开启远程访问 首先在服务器打开 Docker 的服务文件 vim /usr/lib/systemd/system/docker.service修改…

ubuntu下安装配置python3.11

方案1 添加仓库: $ sudo add-apt-repository ppa:deadsnakes/ppa $ sudo apt update $ sudo apt install python3.11然后查看有多少个python版本已经安装了: ls -l /usr/bin/python*python2.7,python 3.8 ,python 3.11. 然后,设置系统默认…

贪吃蛇小游戏(c语言)

1.效果展示 屏幕录制 2024-04-28 205129 2.基本功能 • 贪吃蛇地图绘制 • 蛇吃食物的功能 (上、下、左、右方键控制蛇的动作) • 蛇撞墙死亡 • 蛇撞自身死亡 • 计算得分 • 蛇身加速、减速 • 暂停游戏 3.技术要点 C语言函数、枚举、结构…

VPot-Free一款功能强大的文字转语音工具 v2306

01 软件介绍 VPot-FREE是一款功能强大的免费文字转语音工具,为用户提供了便捷的语音合成功能。无论是想将文字转化为语音进行朗读,还是将文章转为语音保存,VPot-FREE都能满足你的需求。 多种语音风格可供选择,包括男声、女声以及…

C语言-嵌入式-STM32:FreeRTOS说明和详解

Free即免费的,RTOS的全称是Real time operating system,中文就是实时操作系统。 注意:RTOS不是指某一个确定的系统,而是指一类操作系统。比如:uc/OS,FreeRTOS,RTX,RT-Thread 等这些都…

如何利用快解析远程访问NAS、FTP、Web服务

什么是内网、外网? 所谓内网就是内部建立的局域网络或办公网络。一家公司或一个家庭有多台计算机,他们利用不同网络布局将这一台或多台计算机或其它设备连接起来构成一个局部的办公或者资源共享网络,我们就称它为内部网络,也叫内…

【MySQL精炼宝库】深度解析索引 | 事务

目录 一、索引 1.1 索引(index)概念: 1.2 索引的作用: 1.3 索引的缺点: 1.4 索引的使用场景: 1.5 索引的使用: 1.6 面试题:索引底层的数据结构(核心内容): 1.7 索引列查询(主…

FSNotes for Mac v6.7.1中文激活:轻量级笔记管理工具

FSNotes for Mac,一款专为Mac用户打造的轻量级笔记管理工具,让您的笔记管理变得简单而高效。 FSNotes for Mac v6.7.1中文激活版下载 它采用Markdown文件格式,让您轻松创建和编辑富文本笔记,无需担心格式问题。同时,FS…