InnoDB简介

  1. InnoDB是Mysql中的一个存储引擎 , 用来将数据存储到磁盘上
  2. InnoDB将数据划分为若干页 , 以页的形式来进行数据的存放 , 一页的大小最多为16KB

InnoDB行格式

  1. Compact

    1. ![](https://cdn.nlark.com/yuque/0/2020/webp/2335280/1606807706099-7a415800-fa49-4111-8424-22198ab6d813.webp#align=left&display=inline&height=174&margin=%5Bobject%20Object%5D&originHeight=250&originWidth=783&size=0&status=done&style=none&width=546)
    1. 变长字段长度列表 : 变长字段中存储多少字节的数据是不固定的,所以我们在存储真实数据的时候需要顺便把这些数据占用的字节数也存起来
      1. 需要根据具体的字符集(utf8 , gbk , ascii )针对单个字符存储所需要的字节数来进行判断需要存储的字节数量
      2. 并不是所有记录都需要有变长字段长度列表的存在 , 如果所有的字段都不是变长的数据类型的话,这一部分就不需要有
    2. NULL值列表 : 为了不浪费空间 , 为NULL的值要单独的进行存储 , 只有允许为NULL的列才会存在NULL值列表
      1. 列表用二进制位按照逆序排列 , 二进制位为1 , 代表为NULL , 二进制位0 , 代表不为NULL
      2. 因为是逆序的 , 所以第一列需要和最后一位二进制数位对应 , NULL值列表规定 , 必须用整数个字节(一个字节占8位)来表示 , 如果数量不够 , 则在高位补0 , 最后在用十六进制表示存放在记录格式中 , 针对一个三列值都不为NULL的NULL值列表表示如下图 : InnoDB记录存储结构 - 图1
    3. 记录头信息 : 除了上述两个列表之外 , 此信息是5个字节的的存储大小 , 不同的位数代表了不同的意思 | 名称 | 大小(单位:bit) | 描述 | | :—-: | :—-: | :—-: |
预留位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 表示下一条记录的相对位置
  1. 记录的真实数据 : 记录真实的数据的存储
    1. 除了自己定义的列之外 , Mysql还为记录创建了隐藏列 : DB_ROW_ID、DB_TRX_ID、DB_ROLL_PTR , 其中InnoDB有一项对表主键的生成策略 , 如果没有定义主键 , 则会默认创建DB_ROW_ID 来做为主键
    2. 除了这三个列之外就是我们自己的真实数据 , 需要根据使用的字符集来做存放 , 例如 , 使用的是 ascii 字符集, 那么 0x61616161 就表示 ‘aaaa’ , 以此类推
    3. 其中CHAR(M)类型的列比较特殊 , 对于 CHAR(M) 类型的列来说,当列采用的是定长字符集时,该列占用的字节数不会被加到变长字段长度列表,而如果采用变长字符集时,该列占用的字节数也会被加到变长字段长度列表
  1. Redundant

    此行格式是Mysql5.0之前采用 , 随着版本迭代更新的原因 , 就不多做记录 , 仅展示行格式内容

InnoDB记录存储结构 - 图2

行溢出数据

  • Mysql中存储数据的基本但是 , 一页的大小是16KB , 当某条数据占用字节过大 , 导致一页数据无法存储时 , 会发生行溢出 , 此时在行数据中记录的真实数据 , 只会存放一部分数据内容和20字节用来记录其余数据存放的地址

InnoDB记录存储结构 - 图3