MyISAM表存储格式
MyISAM
支持三种不同的存储格式。根据您使用的列的类型,自动选择固定格式和动态格式这两种格式。第三种压缩格式只能使用myisampack实用程序创建(请参见“myisampack—生成压缩的只读MyISAM表”)。
当将CREATE TABLE
或ALTER TABLE
用于没有BLOB
或TEXT
列的表时,可以将表格式强制为FIXED
或DYNAMIC
与ROW_FORMAT
table选项一起使用。
见第13.1.20,“CREATE TABLE语句”,有关的信息ROW_FORMAT
。
您可以MyISAM
使用myisamchk解压缩(解压缩)压缩表--unpack
;有关更多信息,请参见“myisamchk-MyISAM表维护实用程序”。
静态(固定长度)表特征
MyISAM
表格的默认格式是静态格式。当表不包含可变长度列它用于(VARCHAR
,VARBINARY
,BLOB
,或TEXT
)。每行使用固定数量的字节存储。
在这三种MyISAM
存储格式中,静态格式是最简单,最安全的(最容易损坏)。由于在磁盘上可以轻松找到数据文件中的行,因此它也是最快的磁盘格式:要基于索引中的行号查找行,请将行号乘以行长计算行位置。同样,在扫描表时,每次磁盘读取操作都非常容易读取恒定数量的行。
如果您的计算机在MySQL服务器写入固定格式的MyISAM
文件时崩溃了,则可以证明该安全性。在这种情况下,myisamchk可以轻松确定每一行的起点和终点,因此通常可以回收除部分写入的所有行之外的所有行。MyISAM
表索引始终可以根据数据行进行重构。
注意定长行格式仅适用于没有
BLOB
或TEXT
列的表。用这些带有显式ROW_FORMAT
子句的列创建表不会引发错误或警告;格式规范将被忽略。
静态格式表具有以下特征:
CHAR
和VARCHAR
列用空格填充到指定的列宽,尽管列类型未更改。BINARY
和VARBINARY
列用0x00
字节填充到列的宽度。NULL
列在行中需要额外的空间以记录其值是否为NULL
。每NULL
列多花一位,四舍五入到最接近的字节。- 很快。
- 易于缓存。
- 崩溃后易于重构,因为行位于固定位置。
- 除非您删除大量的行并希望将可用磁盘空间返回给操作系统,否则不需要进行重组。为此,请使用
OPTIMIZE TABLE
或myisamchk -r。 - 通常需要比动态格式表更多的磁盘空间。
使用以下表达式计算静态大小的行的预期行长度(以字节为单位):
row length = 1 + (sum of column lengths) + (number of NULL columns + delete_flag + 7)/8 + (number of variable-length columns)
delete_flag
对于具有静态行格式的表,该值为1。静态表使用行记录中的一位作为标志,以指示该行是否已被删除。delete_flag
对于动态表为0,因为该标志存储在动态行标题中。
动态表特征
如果使用动态存储格式MyISAM
表包含任何可变长度列(VARCHAR
,VARBINARY
,BLOB
,或TEXT
),或者如果表用所创建的ROW_FORMAT=DYNAMIC
表的选项。
动态格式比静态格式稍微复杂一点,因为每一行都有一个标头,指示它有多长时间。如果由于更新而使行变长,则行可能会变得碎片化(存储在不连续的碎片中)。
您可以使用OPTIMIZE TABLE
或myisamchk -r对表进行碎片整理。如果在包含一些可变长度列的表中有经常访问或更改的固定长度列,则最好将可变长度列移至其他表以避免碎片。
动态格式表具有以下特征:
- 除了长度小于四的字符串列之外,所有字符串列都是动态的。
- 每行前面都有一个位图,该位图指示哪些列包含空字符串(对于字符串列)或零(对于数字列)。这不包括包含
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。
压缩表特征
压缩存储格式是使用myisampack工具生成的只读格式。可以使用myisamchk来解压缩压缩表。
压缩表具有以下特征:
- 压缩表只占用很少的磁盘空间。这样可以最大程度地减少磁盘使用,这在使用慢速磁盘(例如CD-ROM)时很有用。
每行分别进行压缩,因此访问开销很小。根据表中最大的行,行的标题占用一到三个字节。每列的压缩方式不同。每列通常有不同的霍夫曼树。一些压缩类型是:
- 后缀空间压缩。
- 前缀空间压缩。
- 值为零的数字使用一位存储。
- 如果整数列中的值范围较小,则使用最小的类型存储该列。例如,如果
BIGINT
列(八个字节)的TINYINT
所有值都在从-128
到的范围内,则可以将其存储为列(一个字节)127
。 - 如果一列只有少量的可能值,则数据类型将转换为
ENUM
。 - 列可以使用前述压缩类型的任意组合。
- 可以用于固定长度或动态长度的行。
注意虽然压缩表是只读的,因此您不能更新或添加表中的行,但DDL(数据定义语言)操作仍然有效。例如,您可能仍然会
DROP
用来删除表并TRUNCATE TABLE
清空表。