数据库给使用者最直观的感觉,就是库、表、行、字段,这些概念都是逻辑上的。前面我们深入讲解了Buffer Pool的内部原理,它的基本存储单位是默认大小为16K的页。每页都保存了一行一行的数据。我们按照数据页为单位把磁盘上的数据加载到内存的缓存页里来,也是按照页为单位,把缓存页的数据刷入磁盘的数据页中。

而我们常常听到数据页、数据区、表空间这些名词,其实这些名词是物理层面上的概念。我们不经要问,库、表、行、字段,这些逻辑上的概念是如何对应到物理层的概念上的呢?我们查询一行数据,是如何找到条数据所在的数据页的呢?

接下来,笔者用几篇文章,讲解下MySQL的表空间、数据区、数据页这些概念,当大家明白搞明白这些东西后,就自然理解上面的问题了。

行格式

行格式即行记录的物理存储格式,决定了这张表数据的物理存储方式,会影响crud性能。

指定行格式

CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名称;
ALTER TABLE 表名 ROW_FORMAT=行格式名称;

InnoDB 包含以下四种行格式

  • Compact

  • Redundant

  • Dynamic

  • Compressed

mysql5.7之前的版本使用的是compact行格式,5.7及以后的版本使用的是dynamic行格式。Compact和Dynamic应用较广泛,compact是目前使用最多的一种,而dynamic是新版本默认的行记录格式。

初识MySQL行数据存储格式

我们这里就以Compact存储格式来讲解。

Compact行格式下,每行数据的存储格式,大概是这样的:

变长字段(记录的长度)列表,null值列表,数据头,col1的值,col2的值,col3的值......

Compact 中一条完整的记录可以被分成'记录的额外信息'和'记录的真实数据' 两部分,其他三种存储存储格式基本大同小异。

变长字段是如何存储的?

MySQL中变长字段长度是不固定的, 比如VARCHAR(50),实际存储的内容可能是"hello",也可能是“hello world"。

所以,我们要读取这类数据字段,必须要知道它的长度。

比如一行数据,它的几个字段为VARCHAR(10), VARCHAR(5)
,VARCHAR(20),CHAR(1),CHAR(1),插入一行数据:hello, ni, hao, a, b。

此时磁盘中存储的行开头的变长字段长度列表,必须存储几个变长字段的长度,需要注意的是,这里是逆序存储的。

行数据存储格式是这样的:

0x03 0x02 0x05 null值列表 头字段 hello, ni, hao, a, b

NULL值列表

null值列表,说的就是一行数据里可能有的字段是选填的,值可以是null。比如name字段,如果允许为null,那么实际存储的时候,要标记出来。

为了节省存储空间,MySQL设计的时候,使用二进制的bit位来存储null值列表。

假如创建了一张表:

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

user表5个字段,4个变长的,只有name是非NULL的,其他的4个字段都是可以为NULL的。

假如现在插入一行数据:zhangsan NULL M NULL Tsinghua,address和job是NULL,那么它在磁盘上是怎么存储的?

NULL值列表,是这样存储的,你所有允许值为NULL的字段,都会有一个二进制的bit值,bit值为1说明是NULL,如果bit值为0说明不是NULL。

上面插入的那行数据,address、gender、job、school4个字段都允许为NULL,每个字段都会有一个bit位,其中address与job是NULL,所有4个bit位应该是:1010。

而且NULL值列表也是逆序存储的,所以NULL值列表里是0101。

一般NULL值列表是8个bit位的倍数,如果不足8个bit位,则高位补0。

所以现在看来,行数据存储格式是这样的:

0x08 0x08 00000101 头信息 col1的值,col2的值,col3的值......

数据头以及真实数据

行数据的头长度是固定的40bit,第一个bit和第二个bit,都是预留的,暂时没有用到。

记录头信息详细如下表所示,有的暂时没有用到,可以暂时不用深究它。

现在再加上数据头部分,上面的行存储格式就变成这样了,

0x08 0x08 00000101 0000000000000000000010000000000000011001 zhangsan M Tsinghua

刚开始先是变长字段的长度,用16进制表示,然后是NULL值列表,标识哪些值是NULL,接着是40bit的数据头,最后是真实数据。

在读取数据的时候,也会根据变长字段的长度,先读取出长度为8的zhangsan。

然后发现第二个字段是NULL,就不用再读了。

第三个字段是定长的1,就直接读取出gender为M。

第四个字段是NULL,就不用再读了。

第五个字段变长,长度是8,再读取长度为8的Tsinghua。

然而,真正磁盘上存储的时候,那些字符串就是直接存储在磁盘上的吗?

实际上,字符串都是根据数据库指定的字符集编码,进行编码之后再存储的,编码后大概是这样的:

0x08 0x08 00000101 0000000000000000000010000000000000011001 341324 134546 9342345

大家会看到上面,字符串和其他类型的数值最终都会根据数据库字符集编码,变成一些数字和符号存储在磁盘上。

最后,在实际存储一行数据的时候,MySQL还会给每条记录,加入一些隐藏字段。如下表:

如果用户没有指定主键,且表中没有Unique键时才会使用DB_ROW_ID作为主键。

最终,上面那条数据的存储格式,变成这样了:

0x08 0x08 00000101 0000000000000000000010000000000000011001 00000000034C(DB_ROW_ID)00000000036D(DB_TRX_ID) EA000010022B(DB_ROL_PTR) 341324 134546 9342345

到这里为止,我们基本把一行数据在磁盘上是如何存储的讲清楚了。

有道无术,术可成;有术无道,止于术

欢迎大家关注Java之道公众号

好文章,我在看❤️

一文讲清,MySQL数据库一行数据在磁盘上是怎么存储的?相关推荐

  1. 从零开始学 MySQL —数据库和数据表操作

    ​前言 今天我们学习下核心的内容,学习并实践如何对数据库表和表中的内容做修改,删除,重命名等操作.(想看看周末还有多少爱学习的小伙伴,你们在哪里呀,O(∩_∩)O哈哈~) 1.目录 数据库操作:删除数 ...

  2. 一文搞懂MySQL数据库分库分表

    如果数据量过大,大家一般会分库分表.分库需要注意的内容比较少,但分表需要注意的内容就多了. 工作这几年没遇过数据量特别大的业务,那些过亿的数据,因为索引设置合理,单表性能没有影响,所以实战中一直没用过 ...

  3. php如何在mysql数据库里创建表_php创建mysql数据库以及数据表

    php创建mysql数据库以及数据表 用php链接到mysqli,成功后利用,mysqli_query()创建数据库以及数据表. $con = mysqli_connect("localho ...

  4. mysql数据库输出数据语法错误_获取RDS-Mysql数据语法错误

    如果加工规则中涉及RDS资源的加载,则有可能会产生资源的加载或刷新错误.本文档主要介绍从RDS-Mysql获取数据出错的原因以及排查处理方法. 在成功读取源Logstore数据后,加工引擎开始对源Lo ...

  5. mysql从库数据源_SoapUI Pro教程:如何使用MySQL服务器作为数据源-从MySQL数据库获取数据...

    SoapUI Pro拥有许多其他web服务测试工具所不具备的高级技术和功能.对于REST.SOAP以及其他流行的API和物联网协议,SoapUI Pro提供了业界最全面的功能测试功能.通过易用的图形界 ...

  6. Canal 实现 Mysql数据库实时数据同步

    简介 1.1 canal介绍 Canal是一个基于MySQL二进制日志的高性能数据同步系统.Canal广泛用于阿里巴巴集团(包括https://www.taobao.com),以提供可靠的低延迟增量数 ...

  7. 面试必问:一文弄懂MySQL数据库索引之底层数据结构和索引类型

    面试必问:一文弄懂MySQL数据库索引之底层数据结构和索引类型 前言 一.索引 1.1作用 1.2特点 1.3使用 1.3.1创建索引 1.3.2删除索引 1.3.3查看表中的索引 1.3.4查看SQ ...

  8. 一文讲清-NFT市场新秀SudoSwap的AMM机制-创新挑战与局限

    NFT交易市场的近期颓势频现,整个市场的流动性大幅降低,而此时8月异军突起的SudoSwap则凭借一超多强的增长数据,让基于AMM机制的交易市场映入大众视野. 基于链上数据分析截至8.20日,已有上千 ...

  9. mysql数据库删除数据的三种方式:

    mysql数据库删除数据的三种方式: delete from table where 直接删除表中的某一行数据,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作.所以delete相 ...

最新文章

  1. 《ActionScript 3.0基础教程》——1.4 对象参数
  2. 【html、CSS、javascript-8】JavaScript作用域
  3. CF1392G-Omkar and Pies【dp】
  4. 从地址栏中敲入一个网址,到网页显示出来,这个过程经历了什么
  5. 华为手机云闪付付款码如何截图_云闪付乘车码,它带着优惠又来了
  6. 会议交流 | DataFunCon 线上大会 - 知识图谱专题论坛
  7. 学习: 导航器添加修饰符
  8. 湖科大计算机科学与技术,湖南科技大学计算机科学与工程学院前来我院进行访问与交流...
  9. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_3_字节输出流_OutputStream类FileOutputStream...
  10. [转载]github在线更改mysql表结构工具gh-ost
  11. 周长相等的正方形面积一定相等_周长和面积一直是三年级孩子的易失分点,家长要把好关!...
  12. 【历史上的今天】7 月 3 日:人体工程学标准法案;消费电子领域先驱诞生;育碧发布 Uplay
  13. QQ、微信动态图表情包怎么制作?视频如何转GIF
  14. 关于嵌入式的bin、hex、axf、map
  15. 【Tableau Desktop 企业日常问题20】Tableau怎么折线变虚线?
  16. 前世档案 分数 20作者 陈越单位 浙江大学
  17. 海洋测绘各种数据考点
  18. 倩女幽魂偃师技能攻略介绍:偃师技能怎么玩?
  19. windows7计算机无法到达,win7电脑突然无法进入到安全模式了怎么办?
  20. Linux版本Java卸载

热门文章

  1. C/C++ OpenCV五种滤波器综合示例
  2. python中shift函数rolling_【邢不行|量化小讲堂系列18-Python量化入门】简易波动指标(EMV)策略实证...
  3. mybatis like模糊查询_Java自学之mybatis:模糊查询和多条件查询
  4. 计算机中专专业是什么意思,计算机专业的中专与大专有什么不同?
  5. eclipemaven本地仓库依赖_【Maven】解决本地jar依赖
  6. android R制作OTA包时报错
  7. linux 统计目录大小并按大小排序
  8. 瑶琳c语言,来桐庐瑶琳仙境,开启一场18°C的奇妙之旅
  9. LeetCode篇之链表:1290(二进制链表转整数)
  10. (计算机组成原理)第二章数据的表示和运算-第二节4:定点数的加减运算和溢出判断