主键的生成策略


  • 优先使用用户自定义主键作为主键。
  • 如果用户没有定义主键,则选取一个Unique键作为主键。
  • 如果表中连Unique键都没有定义的话,则InnoDB会为表默认添加一个名为row_id的隐藏列作为主键。

行格式

  • InnoDB存储引擎设计了4种不同类型的行格式,分别是Compact、Redundant、Dynamic和Compressed行格式。

COMPACT行格式

MySQL中InnoDB引擎底层存储_database


  • 变长字段:比如VARCHAR(M)、VARBINARY(M)、各种TEXT类型,各种BLOB类型…他的储存长度是不固定的,我们在存储的时候也要把这个字段实际多长记录起来
  • null值列表:每个允许存储NULL的列对应一个二进制位,二进制位的值为1时,代表该列的值为NULL。
  • 记录头信息:由固定的5个字节组成。5个字节也就是40个二进制位,不同的位代表不同的意思。

字段信息

占用位数

代表的含义

预留位1

1

没有使用

预留位2

1

没有使用

delete_mask

1

标记该记录是否被删除,删除的数据会在页上记录一个删除列表,之后有新数据插入会覆盖当前的位置

min_rec_mask

1

B+树的每层非叶子节点中的最小记录都会添加该标记

n_owned

4

表示当前记录拥有的记录数

heap_no

13

表示当前记录在页的位置信息

record_type

3

表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录

next_record

16

表示下一条记录的相对位置


  • DB_ROW_ID(row_id):非必须,6字节,表示行ID,唯一标识一条记录(没有自定义主键以及Unique键的情况下才会添加该列)
  • DB_TRX_ID:必须,6字节,表示事务ID
  • DB_ROLL_PTR:必须,7字节,表示回滚指针

Redundant行格式

  • Redundant行格式是MySQL5.0之前用的一种行格式,这里不做详细介绍。

Dynamic和Compressed行格式


  • MySQL5.7的默认行格式就是Dynamic
  • Dynamic和Compressed行格式和Compact行格式挺像,只不过在处理行溢出数据时有所不同。
  • Compressed行格式和Dynamic不同的一点是,Compressed行格式会采用压缩算法对页面进行压缩,以节省空间。

索引页格式

  • InnoDB管理存储空间的基本单位,一个页的大小一般是16KB。

MySQL中InnoDB引擎底层存储_主键_02

类型

含义

长度

作用

File Header

文件头部

38字节

页的一些通用信息。包括页的类型(Undo日志页、段信息节点、Insert Buffer空闲列表、Insert Buffer位图、系统页、事务系统数据、表空间头部信息、扩展描述页、溢出页、索引页),这个页的编号是多少,它的上一个页、下一个页是谁,页的校验和等等,这个部分占用固定的38个字节

Page Header

页面头部

56字节

数据页专有的一些信息。InnoDB为了能得到一个数据页中存储的记录的状态信息,比如本页中已经存储了多少条记录,第一条记录的地址是什么,页目录中存储了多少个槽等等,特意在页中定义了一个叫Page Header的部分,它是页结构的第二部分,这个部分占用固定的56个字节,专门存储各种状态信息。

Infimum + Supremum

最小记录和最大记录

26字节

两个虚拟的行记录

User Records

用户记录

大小不确定

实际存储的行记录内容

Free Space

空闲空间

大小不确定

页中尚未使用的空间,这个值被替代完之后,就会开启新的页

Page Directory

页面目录

大小不确定

页中的某些记录的相对位置。将所有记录划分为几组,每组的最后一条数据的头信息中的n_owned属性表示该记录拥有多少条记录,也就是该组内共有几条记录,然后将每个组的最后一条记录的地址偏移量单独提取出来按顺序存储到靠近页的尾部的地方,这个地方就是所谓的Page Directory。(每个分组中的记录条数是有规定的:对于最小记录所在的分组只能有 1 条记录,最大记录所在的分组拥有的记录条数只能在 1~8 条之间,剩下的分组中记录的条数范围只能在是 4~8 条之间。)

File Trailer

文件尾部

8字节

校验页是否完整

结束语


  • 获取更多有价值的文章,让我们一起成为架构师!
  • 关注公众号,可以让你逐步对MySQL以及并发编程有更深入的理解!
  • 这个公众号,无广告!!!每日更新!!!
    MySQL中InnoDB引擎底层存储_主键_03