引言
MySQL是一款支持拔插式引擎的数据库,在开发过程中你可以根据业务特性,从支持的诸多引擎中选择一款适合的,例如MyISAM、InnoDB、Merge、Memory(HEAP)、BDB(BerkeleyDB)、Example、Federated、Archive、CSV、Blackhole.....
不过虽然各款引擎都各有千秋,但其中最为常用的就只有MyISAM、InnoDB这两款引擎。
MyISAM引擎是MySQL官方基于早期的ISAM引擎改良而来的,它是一款“苗根正红”的引擎,由于其不错的性能表现,再加上丰富的特性支持(全文索引、压缩机制、空间索引/函数等),在MySQL5.5版本之前,也一直是MySQL默认的存储引擎。
但随着时间慢慢推移,MySQL官方渐渐有了“新欢”,开始主推使用InnoDB作为表的引擎,甚至到了MySQL5.6及以后版本中,直接用InnoDB代替了MyISAM,作为了MySQL默认的存储引擎,这是啥原因呢?
MyISAM引擎整个实现都由官方一点点开发,甚至MySQL-Server中的不少功能都是为MyISAM而量身定制,其地位在MySQL体系中可以看成是“亲儿子”,而InnoDB由于是其他公司开源的原因,因此其地位可以算作一个“外来子”,但为何“外来子”接替了“亲生子”的职责呢?是MySQL官方始乱终弃嘛?这背后一切的一切到底发生了什么,咱们现在展开来聊一聊这个话题:半道出家的InnoDB为何能替换官方的MyISAM引擎?
不过在正式聊这个话题之前,咱们先对比一下MyISAM、InnoDB这两款最为常用的存储引擎。
一、MyISAM引擎 vs InnoDB引擎
前面介绍了一下MyISAM引擎的背景,那现在也先简单介绍一下InnoDB引擎的背景吧,InnoDB由Innobase Oy公司所开发,其创始人是Heikki Tuuri,提这个名字大家估计不太熟,但提另外一个名字大家绝对知道,也就是Linux操作系统之父Linus,InnoDB的创始人和他正是校友关系,但InnoDB这款引擎的历程也比较艰辛,这里就不做过多介绍了,总之最终在2006.05月也被甲骨文公司并购。
以最经典、最主流的MySQL5.7版本为例,两款引擎各自支持的特性如下:
从上述这摘自官网的两张图中,咱们也很难去对比两者之间的差异,所以还是直接一点吧,以目前已更新的《全解MySQL数据库》系列的文章作为基础,从各个维度及特性支持来做个简单的对比。
2.1、磁盘文件的对比
在《MySQL架构篇-文件系统层》中曾首次简单的聊到过关于不同文件格式的含义,其中就提到过MyISAM、InnoDB两款引擎在存储数据时,本地文件的不同点。同时在《索引原理篇-常规引擎的索引存储》这篇文章中,曾分别使用MyISAM、InnoDB创建了两张表zz_innodb_index、zz_myisam_index,并且也从本地观察了两张表的磁盘文件,如下:
其中使用MyISAM引擎的表:zz_myisam_index,会在本地生成三个磁盘文件:
-
zz_myisam_index.frm:该文件中存储表的结构信息。
-
zz_myisam_index.MYD:该文件中存储表的行数据。
-
zz_myisam_index.MYI:该文件中存储表的索引数据。
从这里可得知一点:MyISAM引擎的表数据和索引数据,会分别放在两个不同的文件中存储。
而反观使用InnoDB引擎的表:zz_innodb_index,在磁盘中仅有两个文件:
-
zz_innodb_index.frm:该文件中存储表的结构信息。
-
zz_innodb_index.ibd:该文件中存储表的行数据和索引数据。
为啥要对比磁盘文件的区别呢?因为这点关乎着后续索引的支持性,咱们接着往下聊。
2.2、索引支持的对比
因为MyISAM引擎在设计之初,会将表分为.frm、.MYD、.MYI三个文件放在磁盘存储,表数据和索引数据是分别放在.MYD、.MYI文件中,所以注定了MyISAM引擎只支持非聚簇索引。而InnoDB引擎的表数据、索引数据都放在.ibd文件中存储,因此InnoDB是支持聚簇索引的。
为啥索引数据和表数据分开存储就不支持聚簇索引呢?这里可参考《索引初识篇-存储方式层次划分索引类型》中给出的定义:
聚簇索引的要求是:索引键和行数据必须在物理空间上也是连续的,而MyISAM表数据和索引数据,分别位于两个磁盘文件中,这也就注定了它无法满足聚簇索引的要求。
一种引擎支不支持聚簇索引很重要,这涉及到了后面的很多技术实现,而MyISAM把表数据和索引数据分开存了,也就意味着MyISAM相较于InnoDB来说,这小子天生就带有缺陷~
但不支持聚簇索引也有好处,也就是无论走任何索引,都只需要一遍查询即可获得数据,而InnoDB引擎的表中,如果不走聚簇(主键)索引查询数据,走其他索引的情况下,都需要经过两遍(回表)查询才能获得数据。
但这也不意味着MyISAM引擎查数据就比InnoDB快,如果看过《高性能MySQL》这本书的小伙伴,应该会知道在其中有一句话:“不要轻易相信「MyISAM比InnoDB快」之类的经验之谈,这个结论往往不是绝对的”。
这句话的原因是啥呢?这点在后面再说,接着再聊一聊其他方面的对比。