如果 MyISAM
表包含任何可变长度列(VARCHAR
、VARBINARY
、BLOB
或 TEXT
),或者表是在使用 ROW_FORMAT=DYNAMIC
表选项的情况下创建的,则使用动态存储格式。
动态格式比静态格式稍微复杂一些,因为每行都有一个标头指示其长度。当由于更新而使行变长时,行可能会变得碎片化(以非连续块存储)。
您可以使用 OPTIMIZE TABLE
或 myisamchk -r 对表进行碎片整理。如果您在包含一些可变长度列的表中具有经常访问或更改的固定长度列,则最好将可变长度列移到其他表中,以避免碎片化。
动态格式表具有以下特性
除了长度小于 4 的字符串列外,所有字符串列都是动态的。
每行前都有一个位图,指示哪些列包含空字符串(对于字符串列)或零(对于数值列)。这并不包括包含
NULL
值的列。如果字符串列在去除尾随空格后长度为零,或者数值列的值为零,则会在位图中标记它,并且不会保存到磁盘。非空字符串会保存为长度字节加字符串内容。NULL
列需要在行中占用额外空间来记录其值是否为NULL
。每个NULL
列会额外占用一个比特,向上取整到最接近的字节。与固定长度表相比,通常需要的磁盘空间要少得多。
每行只使用所需的存储空间。但是,如果行变大,它将被分成所需的块数,从而导致行碎片化。例如,如果您更新包含扩展行长度的信息的行,则该行将变得碎片化。在这种情况下,您可能需要不时运行
OPTIMIZE TABLE
或 myisamchk -r 来提高性能。使用 myisamchk -ei 获取表统计信息。与静态格式表相比,在崩溃后重建难度更大,因为行可能被分割成多个片段,并且链接(片段)可能丢失。
动态大小行的预期行长使用以下表达式计算
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 TABLE
或 myisamchk -r 删除。