存档点1 起始的记录

124 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天

之前提到了数据库中的多种存储引擎,不同的存储引擎底层记录的处理、储存形式也不同,但是从原理上来说,万物皆通

这里我们要介绍的是最常见的InnoDB

也就是说

这是关于InnoDB一条记录的故事

记录的格式

同样的信息,可以有不同的存储形式(格式)

就像一句 “我爱你” 可以用不同的语言演绎

InnoDB中有4中格式:

  • COMPACT行格式
  • Redundant行格式
  • Dynamic行格式
  • Compressed行格式

可以在创建、修改表的时候,指定表的行格式

COMPACT行格式

一条(行)完整的记录:

  • 记录的元数据信息
    • 变长字段长度列表:主要是针对数据长度不固定的数据类型,需要存储其真正占用的字节数
      • 整行记录的变长字段长度按列逆序存放在这个字段
      • 变长字段为NULL时,不会存储长度
      • 当该表列中没有变长字段的时候,不会有这个字段
      • VARCHAR为变长字段类型
      • CHAR使用字节长度不固定的字符集时,也是变长字段类型
      • CHAR(M)会分配足够存储M长度字符的空间,VARCHAR则不会
    • NULL值列表:统一管理值可能为NULL的列
      • 先会看当前表定义中,哪些列可为NULL
      • 若表中没有可为NULL的列,则没有该字段
      • 每一列为一个二进制位(1为NULL,0部位NULL),按列顺序逆序排列
      • 该字段以字节为单位,不满时高位补0
    • 记录头信息:用于描述记录的其他信息
      • 预留位1、预留位2:各1bit
      • delete_mask:1bit,记录是否删除
      • min_rec_mask:1bit,B+树每层叶子节点中最小记录会有该标记
      • next_record:16bit,下一条记录相对地址
      • ......
  • 记录的数据信息:每一列的数据
    • 除了自定义列数据,还有些隐藏列:
      • row_id:行id,记录的唯一标记
      • transaction_id:事务id
      • roll_point:回滚指针
    • 主键选取规则:自定义主键→选取一个Unique键做主键→没有Unique键,添加row_id做主键

元数据信息就是告诉你,你应该怎么解读存储的二进制数据信息、数据信息的存储规则,这样才能置换出真是的数据信息

Redundant行格式

MySQL5.0之前的数据格式了,有点老了

  • 记录的元数据
    • 字段长度偏移信息:所有列的逆序偏移信息,第一位表示当前记录是否为NULL
      • 定长字符串还是会占据空间存储空信息
    • 记录头信息:就是记录头信息,少个record_type,多了个n_feild、1byte_offs_flag
  • 记录的数据

Dynamic、Compressed行格式

和COMPACT格式很像,只是在处理行溢出的时候使用的策略不一样

会将溢出的字段所有数据存储在溢出页,该字段只存储溢出页地址

行溢出

任何东西都不能无限膨胀

MySQL中的一条记录大小也是如此

  • 除了BLOB、TEXT类型列,其他列占用的字节数加起来不能超过65535个字节
    • 实际上只要存储了很大的数据都有可能出现行溢出现象
  • 只会在该字段存储部分数据,剩余的数据在其他页存放,并且该字段使用20个字节存储其他存放地点的地址以及数据长度

交换的基本单位

内存中的数据存储断电后会失效

磁盘中的数据断电后不会丢失

为了长时间存储数据、在内存中处理数据,两者之间的数据交换是必不可少

  • 交换一次数据过少时
    • 交换频率增加
    • 效率降低
  • 交换一次数据过多时
    • 数据丢失可能性更大

在InnoDB中叫数据划分为页,页大小一般为16KB,页为数据交换的基本单位