转载请注明转载自:忆雨林枫

InnoDB REDUNDANT和COMPACT行格式

Redundant行格式的特性

REDUNDANT格式可用来保持着与MySQL老版本的兼容性。
使用REDUNDANT行格式的InnoDB表下面特性:

    • 每个索引记录都含有一个6字节的头部,这个6字节的头部用于将连续的记录链接在一起,同样还用于行级锁。
    • 聚集索引的记录包含所有用户定义的列。此外,还有一个6字节的事务ID字段和一个7字节的滚动指针字段。
    • 如果没有给表定义主键。那么每个聚集索引记录还包含一个6字节的行ID字段。
    • 每个辅助索引记录还包含所有为聚集索引定义,而这些主键字段不在辅助索引中的主键字段。
    • 一个记录包含一个指向记录中每个字段的指针,如果一个记录中字段总长少于128个字节,那么这个指针就是1个字节,否则就是2个字节。这些指针的数组被称为记录目录,指针指向的区域被称为记录的数据。
    • 在内部,InnoDB以储存固定长度字符串列,如 CHAR(10) 是一个固定长度格式。InnoDB不会截断VARCHAR列的结尾空格。
    • InnoDB 将长度大于或等于768字节的固定长度字段编码为可变长度字段,这样可以储存在下一个页。例如: 如果字符集的最大字节长度大于3,那么一个CHAR(255) 列可以超过768字节。就与 utf8mb4一样。
    • SQL中的NULL值在记录目录中保留1个或2个字节。除此之外,如果是储存在可变长度列, NULL值在记录的数据部分是保留0字节。在固定长度的列中,记录中的数据部分是保留列的固定长度, 为NULL值保留固定的空间,使得可以将NULL 更新为非NULL,从而不造成索引页碎片。

COMPACT行格式的特性

REDUNDANT格式相比,COMPACT行格式的行储存空间减少了大约20%,但代价就是某些操作的CPU使用量增加。 如果您的负载是一个典型的受缓存命中率和磁盘速度的限制。 那么使用COMPACT行格式可能会更快,如果负载是受到CPU速度的限制,那么使用COMPACT可能会变得更变。

使用COMPACT行格式的InnoDB表有一下特性:

  • 每个索引记录都含有一个5字节的头部,这个头部可能是变长的。投部用于将连续的记录链接在一起,同样还用于行级锁。
  • 记录头的可变长部分含有一个位向量来表示NULL列。 如果索引中可以被设置为NULL的列的数量是N,那么这个位向量占用 最大(N/8)字节。(举个例子,如果有9 到 15个列可以设置为NULL,那么,这个位向量使用2字节。) 为 NULL的列不占用空间,除了这个位向量。记录头的可变长部分还包含可变长度列的长度。每个长度占用1或2个字节。具体的是取决于列的最大长度。如果索引中的所有列都是 NOT NULL ,并且具有固定的长度,那么记录头就没有可变长部分。
  • 对于每个非-NULL 的变长字段。记录头用1或2个字节来包含列的长度。只有当列的部分被储存在溢出页的外部,或者最大长度超过了255个字节,并且实际长度超过了127个字节时,才需要2个字节。对于一个外部储存的列,2个字节表示内部储存部分的长度,加上指向外部储存部分的20个字节的指针。内部是768字节,因此长度就是768+20。20字节的指针储存你额的真实长度。
  • 记录头后面的是非-NULL 列的数据内容。
  • 聚集索引的记录包含所有用户定义的列。此外,还有一个6字节的事务ID字段和一个7字节的滚动指针字段。
  • 如果没有给表定义主键。那么每个聚集索引记录还包含一个6字节的行ID字段。
  • 每个辅助索引记录还包含所有为聚集索引定义,而这些主键字段不在辅助索引中的主键字段。如果这些主键字段中任何一个是变长,那么辅助索引的记录头会有一个可变长的部分来记录它们的长度,即使,辅助索引是定义在固定长度的列上。
  • 在内部,对于非可变长度的字符集设置,InnoDB以固定长度的格式储存诸如CHAR(10)等固定长度的字符列。InnoDB不会截断VARCHAR列中尾部的空格。
  • 在内部,对于可变长的字符集,如 utf8mb3 和 utf8mb4, 那么 InnoDB将试图通过调整尾部的空间来将 CHAR(N)存储在N 字节中。 如果这个 CHAR(N)列值的长度超过了 N 字节。那么 InnoDB 会将尾部的空间修整为最小的列值字节长度。CHAR(N)列的最大字符字节长度是 × NInnoDB 为 CHAR(N)保留最少N个字节。 在很多情况下,保留最小空间 N可以在不造成索引页碎片的情况下实现列更新。相比之下,对于 ROW_FORMAT=REDUNDANT, CHAR(N) 列占用最大的字符长度 × NInnoDB 将长度大于或等于768字节的固定长度字段编码为可变长度字段,这样可以储存在下一个页。例如: 如果字符集的最大字节长度大于3,那么一个CHAR(255) 列可以超过768字节。就与 utf8mb4一样。
    ROW_FORMAT=DYNAMICROW_FORMAT=COMPRESSED 处理 CHAR 储存的方式和ROW_FORMAT=COMPACT一样。