## 什么是MyISAM? MyISAM是MySQL关系数据库管理系统的默认储存引擎(5.5之前)。这种MySQL表存储结构从旧的ISAM代码扩展 出许多有用的功能。在新版本的MySQL中,InnoDB引擎由于其对事务,参照完整性,以及更高的并发性等优点开始广泛的取代MyISAM。 每一个MyISAM表都对应于硬盘上的三个文件。这三个文件有一样的文件名,但是有不同的扩展名以指示其类型用途:.frm文件保存表的定义,但是这个文件并不是MyISAM引擎的一部分,而是服务器的一部分;.MYD保存表的数据;.MYI是表的索引文件。 ## 什么是InnoDB? InnoDB是MySQL的另一个存储引擎,目前MySQL AB所发行新版的标准,被包含在所有二进制安装包里,5.5之后作为默认的存储引擎。较之于其它的存储引擎它的优点是它支持兼容ACID的事务(类似于PostgreSQL),以及参数 完整性(即对外键的支持)。 Oracle公司与2005年10月收购了Innobase。Innobase采用双认证授权。它使用GNU发行,也允许其它想将InnoDB结合到商业软件的团体获得授权。 目前比较普及的存储引擎是MyISAM和InnoDB。MyISAM与InnoDB的主要的不同点在于性能和事务控制上。MyISAM是早期ISAM(Indexed Sequential Access Method,MySQL5.0之后已经不支持ISAM了)的扩展实现,ISAM被设计为适合处理读频率远大于写频率这样的情况,因此ISAM以及后来的MyISAM都没有考虑对事物的支持,排除了TPM,不需要事务记录,ISAM的查询效率相当可观,而且内存占用很少。 MyISAM在继承了这类优点的同时,与时俱进地提供了大量实用的新特性和相关工具。例如考虑到并发控制,提供了表级锁,虽然MyISAM本身不支持容错,但可以通过 myisamchk进行故障恢复。而且由于MyISAM是每张表使用各自独立的存储文件(MYD数据文件和MYI索引文件),使得备份及恢复十分方便(拷贝覆盖即可),而且还支持在线恢复。与其他存储引擎比较,MyISAM具有检查和修复表格的大多数工具. MyISAM表格可以被压缩,而且它们支持全文(fulltext)搜索。它们不是事务安全的,而且也不支持外键所以如果你的应用是不需要事务,处理的只是基本的CRUD操作,那么MyISAM是不二选择。 InnoDB被设计成适用于高并发读写的情况,使用MVCC(Multi-Version Concurrency Control)以及行级锁来提供遵从ACID的事务支持。InnoDB支持外键参照完整性,具备故障恢复能力。另外 InnoDB的性能其实还是不错的,特别是在处理大数据量的情况下,用官方的话说就是: InnoDB的CPU效率是其他基于磁盘的关系数据库存储引擎所不能比的。不过InnoDB的备份恢复要麻烦一点,除非你使用了4.1以后版本提供的 Mulit-tablespace支持,因为InnoDB和MyISAM不同,他的数据文件并不是独立对应于每张表的。而是使用的共享表空间,简单的拷贝覆盖方法对他不适用,必须在停掉MYSQL后对进行数据恢复。使用Per-Table Tablespacesd,使其每张表对应一个独立的表空间文件,则情况要简单很多。它与BDB类型具有相同的特性,它们还支持外键。InnoDB表格速度很快,具有比BDB还丰富的特性,因此如果需要一个事务安全的存储引擎,建议使用它。 一般来说,如果需要事务支持,并且有较高的并发读写频率,InnoDB是不错的选择。要是并发读写频率不高的话,其实可以考虑BDB,但由于在 MySQL5.1及其以后版本中,将不再提供BDB支持。这个选项也就没有了 InnoDB默认情况下的事务是打开的(set autocommit = 0)就是说每插入一条记录时候,InnoDB类型的表都会把它当作一个单独的事务来处理.所以如果我们插入了10000条记录,而且没有将事务关闭,那么 InnoDB类型的表会把它当作10000个事务来处理,此时插入的总时间是很多的,这个时候一定要首先把事务关掉再插入,这样的速度就很快了 至于Heap和BDB(Berkeley DB),相对来说,普及率不如前两种,但在有些情况下,还是挺适用的Heap存储引擎就是将数据存储在内存中,由于没有磁盘I/O的等待,速度极快。但由于是内存存储引擎,所做的任何修改在服务器重启后都将消失。Heap挺适合做测试的时候使用BDB是MySQL第一款事务安全的存储引擎。在Berkeley DB database library的基础上建立,同样是事务安全的,但BDB的普及率显然不及InnoDB,因为大多数在MySQL中寻找支持事务的存储引擎的同时也在找支 持MVCC或是行级锁定存储引擎,而BDB只支持Page-level Lock。 ## InnoDB引擎 InnoDB是一个事务型的存储引擎,支持回滚,设计目标是处理大数量数据时提供高性能的服务,它在运行时会在内存中建立缓冲池,用于缓冲数据和索引。 ### InnoDB引擎优点 1.支持事务处理、ACID事务特性; 2.实现了SQL标准的四种隔离级别; 3.支持行级锁和外键约束; 4.可以利用事务日志进行数据恢复。 5.锁级别为行锁,行锁优点是适用于高并发的频繁表修改,高并发是性能优于 MyISAM。缺点是系统消耗较大。 6.索引不仅缓存自身,也缓存数据,相比 MyISAM 需要更大的内存。 ### InnoDB引擎缺点 因为它没有保存表的行数,当使用COUNT统计时会扫描全表。 ## MyISAM引擎 MyISAM 是 MySQL 5.5.5 之前的默认引擎,它的设计目标是快速读取。 ### MyISAM引擎优点 1.高性能读取; 2.因为它保存了表的行数,当使用COUNT统计时不会扫描全表; ### MyISAM引擎缺点 1.锁级别为表锁,表锁优点是开销小,加锁快;缺点是锁粒度大,发生锁冲动概率较高,容纳并发能力低,这个引擎适合查询为主的业务。 2.此引擎不支持事务,也不支持外键。 3.INSERT和UPDATE操作需要锁定整个表; 4.它存储表的行数,于是SELECT COUNT(*) FROM TABLE时只需要直接读取已经保存好的值而不需要进行全表扫描。 ## 适用场景 MyISAM适合:(1)做很多count 的计算;(2)插入不频繁,查询非常频繁;(3)没有事务。 InnoDB适合:(1)可靠性要求比较高,或者要求事务;(2)表更新和查询都相当的频繁,并且表锁定的机会比较大的情况。 ## 表格对比 | 属性 | MyISAM | Heap | BDB | InnoDB | | --- | --- | --- | --- | --- | | 事务 | 不支持 | 不支持 | 支持 | 支持 | | 锁粒度 | 表锁 | 表锁 | 页锁(page, 8KB) | 行锁 | | 存储 | 拆分文件 | 内存中 | 每个表一个文件 | 表空间 | | 隔离等级 | 无 | 无 | 读已提交 | 所有 | | 可移植格式 | 是 | N/A | 否 | 是 | | 引用完整性 | 否 | 否 | 否 | 是 | | 数据主键 | 否 | 否 | 是 | 是 | | MySQL缓存数据记录 | 无 | 有 | 有 | 有 | | 可用性 | 全版本 | 全版本 | MySQL-Max | 全版本 | ## 一些细节上的差别 1. InnoDB不支持FULLTEXT类型的索引,MySQL5.6之后已经支持(实验性)。 2. InnoDB中不保存表的 具体行数,也就是说,执行select count() from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count()语句包含 where条件时,两种表的操作是一样的。 3. 对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引。 4. DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。 5. LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的表不适用。 6. 另外,InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表。