type
status
date
slug
summary
tags
category
icon
password
前提:本文讲述基于 InnoDB 引擎讲述
什么是行 ?
在MySQL中,行(Row)是数据库表中的基本单位。每个表由多个行组成,每一行表示表中的一个记录或数据项。
行由一组相关的列(列也被称为字段)组成,这些列定义了存储在该行中的数据的特征和属性。每个列都有一个特定的数据类型,例如整数、字符、日期等。
通过在表中插入新行,可以将数据添加到数据库中。每个行代表一个实体或对象的实例,并且包含与该实体相关的信息。
行提供了对数据库中存储的数据的访问方式。通过查询和过滤行,可以检索特定条件下的数据,并进行各种操作和分析。
总而言之,行是数据库表中存储数据的基本单位,它们组成了表的结构,并用于表示和操作相关的数据。
MySQL 有哪些行格式 && 怎么设置行格式 ?
InnoDB存储引擎的大佬们到现在为止设计了4种不同类型的行格式,分别是
Compact
、Redundant
、Dynamic(MySQL默认行格式)
和 Compressed行格式
,随着时间的推移,他们可能会设计出更多的行格式,但是不管怎么变,在原理上大体都是相同的。设置行格式
查询表的行格式
在查询结果中可以看到
Row_format
对应的值为 Dynamic
(如果未曾设置行格式)Compact 行格式详解
因为所有的行格式原理都是相同所以我们这里以 compact 行格式来进行介绍,下图就是 compact 行格式组成:
- 变长字段长度列表
- NULL 值列表
- 记录头信息
- 列值信息

准备(创建表)
变长字段长度列表
什么是变长字段长度列表呢 ?我们知道 MySQL 存在一些变长的数据类型。例如:VARCHAR(N), TEXT, BLOB 等类型。当某一字段设置了变长类型,就可以称此字段为变长字段,当我们设置这个字段值的时候存储在内存中的字节是不固定的,所以我们需要记录下此字段占用的字节数。记录上述信息的地方就是变成字段长度列表。
注意📢:变长字段长度列表的存储方式是按照列的逆序来进行存储的
例如我们创建这样一个数据:我们将会得到如下行结构:

NULL 值列表
为什么需要存在 NULL 值列表,因为如果把 NULL 存放在列值中就产生了无用的开销,所以 MySQL 的大佬将它放在 NULL 列表中每个 NULL 值只占用了 1 bit 这样是不是很节省空间。
为了接下来更清晰的描述 NULL 存储我们需要执行以下操作,设置相应的字段可以为 NULL:
然后我们在插入这样一条信息:
之后我们将会得到以下行格式:

你是不是一定很好奇
01
是怎么来的?接下来我们来一起探索。
我们需要知道以下几点 NULL 值列表的存储特性,自然就知道 01 是怎么来的了:- NULL 值列表是使用 bit 来存储 NULL 值信息的,1 对应的是该列为NULL,0 为该列不为 NULL。
- NULL 列表和变长字段长度列表一样也是逆序存储
- NULL 最小存储单位为 1 字节如果高位无值那么 0 进行补位
根据以上特性,我们就能知道上面信息对应的二进制为 00000001 转换为 16 进制为 0x01,到这里你一定知道 01 是怎么来的吧。
记录头信息
记录头这里只是看下这里大概有些什么不需要非常清晰的记住因为他们每个字段在不同场景有着相应的作用

行其他重要信息

row_id:
每条记录的唯一 ID,如果我们设置了主键 ID 此字段将不存在,如未设置主键 ID 系统将自动设置 row_id 的值transaction_id:
最后操作行记录的事务 id,MVCC 实现的关键的一个指标roll_pointer:
回滚指针,指向 undo 日志对应的一条记录行溢出
行溢出是指在数据库表中,某一行的数据大小超过了存储引擎所允许的最大限制。当一行的数据大小超过了存储引擎的限制时,存储引擎会将该行的部分或全部数据存储在其他位置,而不是将其完整地存储在行中。
行溢出通常发生在包含大型文本、二进制数据或较长字符串的列上。这些数据可能会导致行的大小超过存储引擎的限制。为了解决这个问题,存储引擎会将溢出的数据存储在其他位置,并在原始行中存储一个指向溢出数据的引用(如指针或页号)。
具体的行溢出处理方式取决于所使用的存储引擎。下面是两个常见的存储引擎的行溢出处理方式:
InnoDB存储引擎:InnoDB存储引擎支持行溢出。当一行的数据大小超过了页的大小限制(默认为16KB)时,InnoDB会将溢出的部分存储在单独的页中,并在原始行中存储一个指向溢出数据的指针。
需要注意的是,行溢出可能会导致性能下降,因为需要额外的I/O操作来读取溢出的数据。因此,在设计数据库表时,应该合理规划字段的大小,避免过大的行数据,以减少行溢出的发生。
Dynamic和Compressed行溢出区别
Dynamic和Compressed行格式,我现在使用的MySQL版本是5.7,它的默认行格式就是Dynamic,这俩行格式和Compact行格式挺像,只不过在处理行溢出数据时有点儿分歧,它们不会在记录的真实数据处存储字段真实数据的前768个字节,而是把所有的字节都存储到其他页面中,只在记录的真实数据处存储其他页面的地址,就像这样:
Compressed行格式和Dynamic不同的一点是,Compressed行格式会采用压缩算法对页面进行压缩,以节省空间。
- Author:iLikeBug
- URL:http://ilikebug.blog/MySQL/mysql-row
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!