15.2.3.2 动态 tableFeature

如果MyISAMtable 包含任何可变长度的列(VARCHARVARBINARYBLOBTEXT),或者使用ROW_FORMAT=DYNAMIC table 选项创建了 table,则使用动态存储格式。

动态格式比静态格式稍微复杂一点,因为每一行都有一个 Headers,指示它有多长时间。如果由于更新而使行变长,则行可能会变得碎片化(存储在不连续的碎片中)。

您可以使用OPTIMIZE TABLEmyisamchk -r对 table 进行碎片整理。如果在包含一些可变长度列的 table 中有经常访问或更改的固定长度列,则最好将可变长度列移至其他 table 以避免碎片化。

动态格式 table 具有以下 Feature:

  • 除长度小于四的字符串列外,所有字符串列都是动态的。

  • 每行前都有一个位图,该位图指示哪些列包含空字符串(对于字符串列)或零(对于数字列)。这不包括包含NULL值的列。如果在删除尾随空格后字符串列的长度为零,或者数字列的值为零,则它会在位图中标记,并且不会保存到磁盘。非空字符串将另存为长度字节加上字符串内容。

  • NULL列在行中需要额外的空间以记录其值是否为NULL。每个NULL列都多加一位,四舍五入到最接近的字节。

  • 与固定长度 table 相比,通常所需磁盘空间要少得多。

  • 每行仅使用所需的空间。但是,如果一行变大,则会将其拆分为所需的多个碎片,从而导致行碎片化。例如,如果使用扩展行长度的信息更新行,则该行将变得碎片化。在这种情况下,您可能需要不时运行OPTIMIZE TABLEmyisamchk -r来提高性能。使用myisamchk -ei获取 table 统计信息。

  • 崩溃后,要比静态格式的 table 更难重构,因为行可能会分成许多碎片,并且可能会丢失链接(碎片)。

  • 动态大小的行的预期行长使用以下 table 达式计算:

3
+ (number of columns + 7) / 8
+ (number of char columns)
+ (packed size of numeric columns)
+ (length of strings)
+ (number of NULL columns + 7) / 8

每个链接有 6 个字节的罚款。每当更新导致行扩大时,就会链接动态行。每个新链接至少有 20 个字节,因此下一个扩展可能在同一链接中进行。如果不是,则创建另一个链接。您可以使用myisamchk -ed查找链接数。所有链接都可以使用OPTIMIZE TABLEmyisamchk -r删除。