谈谈数据库中 MyISAM 与 InnoDB 区别

MyISAM 存储引擎

MyISAM 是 MySQL 中传统的存储引擎类型,基于 ISAM(Indexed Sequential Access Method,有索引的顺序访问方法)架构发展而来。ISAM 是存储记录和文件的标准方法。与其他存储引擎相比,MyISAM 拥有大多数检查和修复表格的工具。MyISAM 表格可以被压缩,且支持全文搜索。

需要注意的是,MyISAM 不是事务安全的,也不支持外键。如果事务回滚,将造成不完全回滚,不具有原子性。因此,如果业务执行大量的 SELECT 查询,MyISAM 是更好的选择。

MyISAM 是 ISAM 表的新版本,具备如下扩展特性:

  • 二进制层次的可移植性。
  • 支持 NULL 列索引。
  • 对变长行比 ISAM 表有更少的碎片。
  • 支持大文件。
  • 更好的索引压缩。
  • 更好的键值统计分布。
  • 更好和更快的 AUTO_INCREMENT 处理。

InnoDB 存储引擎

InnoDB 是事务安全的存储引擎类型。它与 BDB 类型具有相同的特性,并且支持外键。InnoDB 表格速度很快,具有比 BDB 更丰富的特性,因此如果需要一个事务安全的存储引擎,建议使用它。

如果你的数据执行大量的 INSERTUPDATE 操作,出于性能方面的考虑,应该使用 InnoDB 表。对于支持事务的 InnoDB 类型表,影响速度的主要原因是 AUTOCOMMIT 默认设置是打开的。如果程序没有显式调用 BEGIN 开始事务,会导致每插入一条数据就自动 Commit,严重影响速度。可以在执行 SQL 前调用 BEGIN,将多条 SQL 形成一个事务(即使 AUTOCOMMIT 打开也可以),这将大大提高性能。

MyISAM 与 InnoDB 对比

具体区别可以参考下表:

特性MyISAMInnoDB
构成上区别每个 MyISAM 表在磁盘上存储成三个文件,文件名为表名,扩展名代表文件类型:
1. .frm 文件存储表定义;
2. .MYD (MYData) 数据文件的扩展名;
3. .MYI (MYIndex) 索引文件的扩展名。
基于磁盘的资源是 InnoDB 表空间数据文件和它的日志文件。InnoDB 表的大小只受限于操作系统文件的大小(旧版本一般为 2GB)。
事务处理方面强调的是性能,其执行速度比 InnoDB 类型更快,但是不提供事务支持。提供事务支持,支持外键等高级数据库功能。
锁机制表级锁。行级锁。
注意:InnoDB 表的行锁也不是绝对的。如果在执行一个 SQL 语句时 MySQL 不能确定要扫描的范围,InnoDB 表同样会锁全表。例如:update table set num=1 where name like "%aaa%"
操作性能如果执行大量的 SELECT,MyISAM 是更好的选择。1. 如果数据执行大量的 INSERTUPDATE,出于性能考虑,应该使用 InnoDB 表。
2. DELETE FROM table 时,InnoDB 不会重新建立表,而是一行一行地删除。
3. LOAD TABLE FROM MASTER 操作对 InnoDB 是不起作用的。解决方法是首先把 InnoDB 表改成 MyISAM 表,导入数据后再改成 InnoDB 表,但对于使用了额外 InnoDB 特性(例如外键)的表不适用。
AUTO_INCREMENT 字段可以和其他字段一起建立联合索引。必须包含只有该字段的索引。
全文索引支持。不支持 FULLTEXT 类型的索引。
可移植性二进制数据文件可以在不同操作系统中迁移。-

细节与具体实现的差别

以下是一些细节和具体实现的差别补充:

  1. 全文索引:InnoDB 不支持 FULLTEXT 类型的索引。
  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 特性(例如外键)的表不适用。

总结

综上所述,任何一种表都不是万能的。只有针对业务类型来恰当选择合适的表类型,才能最大程度地发挥 MySQL 的性能优势。

说明:本文部分内容基于较早期的 MySQL 版本(如 5.1 及之前)。

  1. 默认引擎:MySQL 5.5 版本之后,默认存储引擎已改为 InnoDB。
  2. 全文索引:MySQL 5.6 版本之后,InnoDB 也开始支持 FULLTEXT 全文索引。
  3. 文件大小:现代版本中 InnoDB 表空间大小限制已远超 2GB。
  4. 命令支持LOAD TABLE FROM MASTER 在新版本中已废弃或移除。
    请根据实际使用的数据库版本参考上述特性。