标题：myisam
简介
索引文件的扩展名是.MYI (MYIndex)。 
要明确表示你想要用一个MyISAM表格，请用ENGINE表选项指出来：
CREATE TABLE t (i INT) ENGINE = MYISAM;
注释：老版本的MySQL使用TYPE而不是ENGINE（例如，TYPE = MYISAM）。MySQL 5.1为向下兼容而支持这个语法，但TYPE现在被轻视，而ENGINE是首先的用法。 
一般地，ENGINE选项是不必要的；除非默认已经被改变了，MyISAM是默认存储引擎。 
你可以用myisamchk工具来检查或修复MyISAM表。请参阅5.9.5.6节，“使用myisamchk做崩溃恢复”。你也可以用myisampack来压缩MyISAM表，让它们占更少的空间。请参阅8.2节，“myisampack，产生压缩、只读的MyISAM表”。 
特征
MyISAM存储引擎的一些特征1.  所有数据值先存储低字节。这使得数据机和操作系统分离。二进制轻便性的唯一要求是机器使用补码（如最近20年的机器有的一样）和IEEE浮点格式（在主流机器中也完全是主导的）。唯一不支持二进制兼容性的机器是嵌入式系统。这些系统有时使用特殊的处理器。
先存储数据低字节并不严重地影响速度；数据行中的字节一般是未联合的，从一个方向读未联合的字节并不比从反向读更占用更多的资源。服务器上的获取列值的代码与其它代码相比并不显得时间紧。 
2.大文件（达63位文件长度）在支持大文件的文件系统和操作系统上被支持。 
3. 当把删除和更新及插入混合的时候，动态尺寸的行更少碎片。这要通过合并相邻被删除的块，以及若下一个块被删除，就扩展到下一块来自动完成。
4.每个MyISAM表最大索引数是64。 这可以通过重新编译来改变。每个索引最大的列数是16个。 
5.最大的键长度是1000字节。这也可以通过编译来改变。对于键长度超过250字节的情况，一个超过1024字节的的键块被用上。 
6. BLOB和TEXT列可以被索引。
7. NULL值被允许在索引的列中。这个占每个键的0-1个字节。 
8. 所有数字键值以高字节为先被存储以允许一个更高地索引压缩。 
9. 当记录以排好序的顺序插入（就像你使用一个AUTO_INCREMENT列之时），索引树被劈开以便高节点仅包含一个键。这改善了索引树的空间利用率。 
10.每表一个AUTO_INCREMENT列的内部处理。MyISAM为INSERT和UPDATE操作自动更新这一列。这使得AUTO_INCREMENT列更快（至少10%）。在序列顶的值被删除之后就不能再利用。（当AUTO_INCREMENT列被定义为多列索引的最后一列，可以出现重使用从序列顶部删除的值的情况）。AUTO_INCREMENT值可用ALTER TABLE或myisamch来重置。
11. 如果数据文件中间的表没有自由块了，在其它线程从表读的同时，你可以INSERT新行到表中。（这被认识为并发操作）。自由块的出现是作为删除行的结果，或者是用比当前内容多的数据对动态长度行更新的结果。当所有自由块被用完（填满），未来的插入又变成并发。 
12.你可以把数据文件和索引文件放在不同目录，用DATA DIRECTORY和INDEX DIRECTORY选项CREATE TABLE以获得更高的速度，请参阅13.1.5节，“CREATE TABLE语法”。 
a.每个字符列可以又不同的字符集，请参阅第10章：“字符集支持”。 
b.在MyISAM索引文件里又一个标志，它表明表是否被正确关闭。如果用--myisam-recover选项启动mysqld，MyISAM表在打开得时候被自动检查，如果被表被不恰当地关闭，就修复表。 
c.如果你用--update-state选项运行myisamchk，它标注表为已检查。myisamchk --fast只检查那些没有这个标志的表。 
d. myisamchk --analyze为部分键存储统计信息，也为整个键存储统计信息。 
e. myisampack可以打包BLOB和VARCHAR列。MyISAM也支持下列特征1.支持true VARCHAR类型；VARCHAR列以存储在2个字节中的长度来开始。 
2.有VARCHAR的表可以有固定或动态记录长度。
3. VARCHAR和CHAR列可以多达64KB。 
4. 一个被搞乱的已计算索引对可对UNIQUE来使用。这允许你在表内任何列的合并上有UNIQUE。（尽管如此，你不能在一个UNIQUE已计算索引上搜索）。
对MyISAM存储引擎，有一个更详细的论坛在 
15.1.1. MyISAM启动选项
下列对mysqld 的选项可用来改变MyISAM表的行为： 
·         --myisam-recover=mode 
设置为崩溃MyISAM表自动恢复的模式。
·         --delay-key-write=ALL 
对任何MyISAM表的写操作之间不要刷新键缓冲区。
注释：如果你要这么做。当表在使用中之时，你应该不使用来自另一个程序的MyISAM表（比如从另一个MySQL服务器或用myisamchk）。这么做会导致索引被破坏。
对使用--delay-key-write的表，使用--external-locking没有帮助。
请参阅5.3.1节，“mysqld命令行选项”。 
下列系统变量影响MyISAM表的行为：
·         bulk_insert_buffer_size 
用在块插入优化中的树缓冲区的大小。注释：这是一个per thread的限制。
·         (OBSOLETE) myisam_max_extra_sort_file_size 
这个参数已经不在MySQL中使用。 
·         myisam_max_sort_file_size 
如果临时文件会变得超过索引，不要使用快速排序索引方法来创建一个索引。注释：这个参数以字节的形式给出。 
·         myisam_sort_buffer_size 
设置恢复表之时使用的缓冲区的尺寸。
请参阅5.3.3节，“服务器系统变量”。 
如果用--myisam-recover选项启动mysqld，自动恢复被激活。在这种情况下，当服务器打开一个MyISAM表之时，服务器会检查是否表被标注为崩溃，或者表的打开计数变量是否不为0且你正用--skip-external-locking运行服务器。如果这些条件的任何一个为真，下列情况发生： 
·         表被查错。
·         如果服务器发现一个错误，它试着做快速表修复（排序且不重新创建数据文件）。 
·         如果修复因为数据文件中的一个错误而失败（例如，一个重复键错误），服务器会再次尝试修复，这一次重建数据文件。 
·         如果修复仍然失败，服务器用旧修复选项方法再重试一次修复（一行接一行地写，不排序）。这个方法应该能修复任何类型的错误，并且需要很低的磁盘空间。 
如果恢复不能够从先前完成的语句里恢复所有行，而且你不能在--myisam-recover选项值指定FORCE，自动修复会终止，并在错误日志里写一条错误信息：
Error: Couldn't repair table: test.g00pages
如果你指定FORCE，取而代之地，类似这样的一个警告被给出：
Warning: Found 344 of 354 rows when repairing ./test/g00pages
注释：如果自动恢复值包括BACKUP，恢复进程创建文件并用tbl_name-datetime.BAK形式取名。你应该有一个cron脚本，它自动把这些文件从数据库目录移到备份媒质上。
15.1.2.键所需的空间
MyISAM表使用B型树索引。你可以粗略地计算索引文件的大小为(key_length+4)/0.67, 加上所有的键之和。当所有键以排序的顺序插入并且表没有任何压缩的键之时，以上估计是对最坏的情况的。
字符串索引是被空间压缩的。如果第一个字符串索引部分是字符串，它也被加前缀压缩。如果字符串列有许多拖曳空间，或字符串列是一个总是不用完全长度的VARCHAR列，空间压缩使得索引文件比最坏情况时的数值要小。前缀压缩被用在以字符串开始的键上。如果有许多具有同一前缀的字符串，前缀压缩是有帮助的。
在MyISAM表，你也可以在创建表的时候通过指定PACK_KEYS=1来前缀压缩数字。当数字被以高字节优先存储之时，若你有许多具有同一前缀的整数键，上述方法是有帮助的。
MyISAM表的存储格式
MyISAM支持三种不同存储格式。
其中两个（固定格式和动态格式)根据正使用的列的类型来自动选择。第三个，即已压缩格式，只能使用myisampack工具来创建。
当你CREATE或ALTER一个没有BLOB或TEXT列的表，你可以用ROW_FORMAT表选项强制表的格式为FIXED或DYNAMIC。这会导致CHAR和VARCHAR列因FIXED格式变成CHAR，或因DYNAMIC格式变成VARCHAR。 
静态（固定长度）表特征静态格式是MyISAM表的默认存储格式。当表不包含变量长度列（VARCHAR, BLOB, 或TEXT）时，使用这个格式。每一行用固定字节数存储。 
MyISAM的三种存储格式中，静态格式就最简单也是最安全的（至少对于崩溃而言）。静态格式也是最快的on-disk格式。快速来自于数据文件中的行在磁盘上被找到的容易方式：当按照索引中的行号查找一个行时，用行长度乘以行号。同样，当扫描一个表的时候，很容易用每个磁盘读操作读一定数量的记录。 
当MySQL服务器正往一个固定格式MyISAM文件写的时候，如果计算机崩溃了，安全是显然的。在这种情况下，myisamchk可以容易地决定每行从哪里开始到哪里结束，所以它通常可以收回所有记录，除了写了一部分的记录。注意，基于数据行，MyISAM表索引可以一直被重新构建。
静态格式表的一般特征：
·         CHAR列对列宽度是空间填补的。
·         非常快。
·         容易缓存。
·         崩溃后容易重建，因为记录位于固定位置。 
·         重新组织是不必要的，除非你删除巨量的记录并且希望为操作系统腾出磁盘空间。为此，可使用OPTIMIZE TABLE或者myisamchk -r。 
·         通常比动态格式表需要更多的磁盘空间。
动态表特征如果一个MyISAM表包含任何可变长度列（VARCHAR, BLOB或TEXTDynamic），或者如果一个表被用ROW_FORMAT=DYNAMIC选项来创建，动态存储格式被使用。
这个格式更为复杂一点，因为每行有一个表明行有多长的头。当一个记录因为更新的结果被变得更长，该记录也可以在超过一个位置处结束。
你可以使用OPTIMIZE TABLE或myisamchk来对一个表整理碎片。如果在一个表中有你频繁访问或改变的固定长度列，表中也有一些可变长度列，仅为避免碎片而把这些可变长度列移到其它表可能是一个好主意。
动态格式表的一般特征：
·         除了长度少于4的列外，所有的字符串列是动态的。 
·         在每个记录前面是一个位图，该位图表明哪一列包含空字符串（对于字符串列）或者0（对于数字列）。注意，这并不包括包含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来找出链接的数目。所有的链接可以用myisamchk -r来移除。 
已压缩表特征已压缩存储格式是由myisampack工具创建的只读格式。 
所有MySQL分发版里都默认包括myisampack。已压缩表可以用myisamchk来解压缩。 
已压缩表有下列特征：
·         已压缩表占据非常小的磁盘空间。这最小化了磁盘用量，当使用缓慢的磁盘（如CD-ROM)之时，这是很有用的。
·         每个记录是被单独压缩的，所以只有非常小的访问开支。依据表中最大的记录，一个记录的头在每个表中占据1到3个字节。每个列被不同地压缩。通常每个列有一个不同的Huffman树。一些压缩类型如下： 
o        后缀空间压缩。
-        前缀空间压缩。
-        零值的数用一个位来存储。
-        如果在一个整型列中的值有一个小的范围，列被用最小可能的类型来存储。比如，一个BIGINT列（8字节），如果所有它的值在-128到127范围内，它可以被存储为TINYINT列（1字节）
-        如果一个列仅有一小组可能的值，列的类型被转化成ENUM。 
-        一个列可以使用先前压缩类型的任意合并。
·         可以处理固定长度或动态长度记录。
MyISAM表方面的问题
MySQL用来存储数据的文件格式已经被广泛测试过，但总是有导致数据表变得损坏的环境。
损坏的MyISAM表即使MyISAM表格式非常可靠（SQL语句对表做的所有改变在语句返回之前被写下），如果下列任何事件发生，你依然可以获得损坏的表： 
·         mysqld进程在写中间被杀掉。
·         发生未预期的计算机关闭（例如，计算机被关闭）。 
·         硬件故障。
·         你可以同时在正被服务器修改的表上使用外部程序（如myisamchk）。 
·         MySQL或MyISAM代码的软件缺陷。 
一个损坏的表的典型症状如下：
·         当在从表中选择数据之时，你得到如下错误：
·                Incorrect key file for table: '...'. Try to repair it
·         查询不能在表中找到行或返回不完全的数据。
你可以用CHECK TABLE statement语句来检查MyISAM表的健康，并用REPAIR TABLE修复一个损坏的MyISAM表。当mysqld不运行之时，你也可以用myisamchk命令检查或修理一个表。请参阅13.5.2.3节，“CHECK TABLE语法”， 13.5.2.6节，“REPAIR TABLE语法”，和5.9.5节，“myisamchk — MyISAM表维护工具”。 
如果你的表变得频繁损坏，你应该试着确定为什么会这样的原因。要明白的最重要的事是表变得损坏是不是因为服务器崩溃的结果。你可以在错误日志中查找最近的restarted mysqld消息来早期验证这个。如果存在这样一个消息，则表损坏是服务器死掉的一个结果是很有可能的。否则，损坏可能在正常操作中发生。这是一个缺陷。你应该试着创建一个展示这个问题的可重复生成的测试案例。请参阅A.4.2节，“如果MySQL保持崩溃，该怎么做” 及E.1.6节，“如果出现表崩溃，请生成测试案例”。 
未被适当关闭的表的问题每个MyISAM索引文件(.MYI)在头有一个计数器，它可以被用来检查一个表是否被恰当地关闭。如果你从CHECK TABLE或myisamchk得到下列警告，意味着这个计数器已经不同步了： 
clients are using or haven't closed the table properly
这个警告并不是完全意味着表已被破坏，但你至少应该检查表。 
计数器的工作方式如下：
·         表在MySQL中第一次被更新，索引文件头的计数器加一。 
·         在未来的更新中，计数器不被改变。
·         当表的最后实例被关闭（因为一个操作FLUSH TABLE或因为在表缓冲区中没有空间）之时，若表已经在任何点被更新，则计数器减一。
·         当你修理或检查表并且发现表完好之时，计数器被重置为零。 
·         要避免与其它可能检查表的进程进行事务的问题，若计数器为零，在关闭时计数器不减一。
换句话来说，计数器只有在下列情况会不同步：
·         MyISAM表不随第一次发出的LOCK TABLES和FLUSH TABLES被复制。
·         MySQL在一次更新和最后关闭之间崩溃（注意，表可能依然完好，因为MySQL总是在每个语句之间为每件事发出写操作）。 
·         一个表被myisamchk --recover或myisamchk --update-state修改，同时被mysqld使用。 
·         多个mysqld服务器正使用表，并且一个服务器在一个表上执行REPAIR TABLE或CHECK TABLE，同时该表也被另一个服务器使用。在这个结构中，使用CHECK TABLE是安全的，虽然你可能从其它服务器上得到警告。尽管如此，REPAIR TABLE应该被避免，因为当一个服务器用一个新的数据文件替代旧的之时，这并没有发送信号到其它服务器上。 
总的来说，在多服务器之间分享一个数据目录是一个坏主意。