引言
本博客知知识概要的描述存储引擎,不会涉及太多细节,因为存储引擎相关特知识点太多,特性和细节需要仔细研究,如果感兴趣可以阅读相关官方文档。
像官方文档中提到的存储引擎是从MySql架构开始描述的,存储引擎处于MySql架构最底层实现。
本博客中只介绍主流引擎MyISAM和InnoDB。
一、引擎罗列
二、存储引擎InnoDB
InnoDB是MySql默认的事务行存储引擎,也是目前使用最广泛的引擎。拥有主流业务的支持特点,如短期内的事务提交和少量的回滚,本身的性能优化和自动崩溃恢复。除非有特别的需求要使用其他引擎,否则应该优先考虑InnoDB。
InnoDB的数据存储在表空间中,表空间是由InnoDB管理的一个黑盒子,有一系列复杂数据文件组成的。而在MySql4.1版本以后支持了将每个表和索引单独分开放在文件中。
InnoDB采用了MVCC来支持高并发,情妾实现了四个标准的隔离级别,默认的是PEPEATABLE READ可重复读,并通过间隙锁防止幻读的出现,而间隙锁使得InnoDB不仅仅会锁定涉及的行,还会对索引中的间隙行进行锁定,以防止幻影行出现。
InnoDB表是基于聚簇索引建立的,详细请阅读相关文档。聚簇索引对主键查询有很高的性能,不过他的二级索引和非主键索引中必须包含主键列,这就使得主键列很大的话他的其他索引都会很大,应当避免这种情况。
InnoDB内部也做了很多优化,包括从磁盘读取数据时采用的可预测性预读,在写操作时的加速插入进行先插入缓冲区的操纵。
三、存储引擎MyISAM
在MySql5.1之前的版本MyISAM是默认的存储引擎,它提供了大量的特性,包括全文检索,压缩等,但是它和InnoDB比起来不支持事务和行锁,而它最大的缺陷就是奔溃后无法安全回复数据,若对于只读数据,表比较小,可以接受崩溃恢复问题可继续使用MyISAM。
MyISAM会将表存储在两个文件中,数据文件和索引文件,分别以.MYD和.MYI结尾。
MyISAM会对整张表加锁,而不是针对行锁,读取时会对所读到的所有表加共享锁,对写入时则对涉及的表加排他锁,所以很明确,在读共享锁时可以写数据,反之不行。
MyISAM的性能上是比InnoDB高的,这一点很好理解,除了简单的设计以外,还有减少了事务和行锁的所带来的额外服务器开支,但影响MyISAM的罪魁祸首还是表锁问题,若所有查询长期处于Locked状态,那么毫无疑问就是表锁的问题。
MyISAM支持全文检索,这是一种基于分词创建的功能,可以支持复杂查询。
四、选择合适的存储引擎
目前MySql默认的存储引擎时InooDB,并且此存储引擎满足所有必要需求,但是根据业务和数据选择更好的存储引擎也可以提高效率。这么多存储引擎我们怎么选择呢?大部分情况下InnoDB是正确的选择。
对于存储引擎的选择简单的归纳为一句话:除非需要用到某些InnoDB不具备的特性,并且没有其他办法代替,否则都应该选择InnoDB引擎。
例如,我们用到MyISAM的全文检索功能,应当优先选择InnoDB搭配Sphinx组合使用,而不是直接使用MyISAM。
如果用不到InnoDB特性,同时其他存储引擎可以更好地满足需求,也可以考虑一下其他存储引擎。
例如,我们不在乎并发和扩展能力了,也不在乎崩溃数据恢复了,而且嫌弃InnoDB数据文件占用空间了,那么可以选择MyISAM。
另外不到万不得已,不推荐使用混合引擎,它们会带来一些潜在bug,本身在存储引擎和服务器之间的交互已经比较复杂了。
-
如果应用需要支持事务,那么应该直接使用InnoDB,它是目前最稳定并且经过验证的选择,如果不需要事务,并且是select和insert操作,那么MyISAM是不错的选择。
-
备份
若你需要热备份那么选择InnoDB是基本的要求。
-
崩溃恢复
数据量比较大的时候,系统崩溃后如何快速的恢复数据是一个值得考虑的问题,相对而言,MyISAM崩溃后发生损坏的概率比InnoDB要高很多,而且恢复速度很慢,即使不需要事务InnoDB也是大多数人的选择。
-
特有的特性
有些时候应用可能以来一些存储引擎,因为它们有些独有的特性,如果你需要用的一些特殊的特性,当时有缺乏一些必要的特性时,那么不得不做一个折中的选择了,更或者在架构上做出一些取舍。因为编程是灵活的,引擎无法完成的需求业务也的变通有时可以满足。
五、其他结论
一些常见的场景
只读或者大部分情况下只读的表
例如一些类目和数据罗列的数据表中,只存在select和insert,典型的读多写少场景,也不介意MyISAM的崩溃恢复问题,那么可以选择MyISAM。不要低估恢复数据的重要性,因为MyISAM不会保证将数据安全的全部写到磁盘上,它只是把数据写到内存中,然后等待操作系统定时定期将数据刷出到磁盘上。
订单处理
如果涉及到订单应用,建议采用InnoDB,因为业务上支持事务成了必须的,另外就是考虑对外间的支持和表设计。
其他结论
不要轻易相信MyISAM比InnoDB快的经验之谈,这个结论不是绝对的。
在已知的场景中InnoDB的速度都让MyISAM望尘莫及,尤其是使用到聚簇索引等。如数据量大小,io请求量,主键和二级索引等。某些场景下在使用MyISAM引擎一开始没有任何问题,随着数据量增大,访问压力增大会迅速恶化,开始出现锁争用,锁等待,死锁最后崩溃引发的数据恢复。
以上大部分结论摘自 --MySql高级性能