在这里对MySQL存储引擎做一个简单的介绍,不会涉及太多细节,详细的存储引擎指南推荐翻阅存储引擎相关官方文档。笔者会在学习之余分享一些个人的学习笔记心得,望与君共勉。
InnoDB存储引擎 InnoDB是MySQL的默认事务型引擎,是学习MySQL必须了解的存储引擎,也是值得开发人员深入学习的对象。InnoDB的职能是处理大量短期事务,短期事务基本不会被回滚。InnoDB的性能和自动崩溃恢复特性,使其在非事务型存储的需求中也大放异彩。除非极端情况,否则InnoDB应该是开发者的首选。
InnoDB的数据存储在表空间中,表空间是由InnoDB管理的一个黑盒子,由一系列数据文件组成。在MySQL4.1以后的版本中,InnoDB可以将每个表的数据和索引存放在单独的文件中。当然InnoDB也支持使用裸设备作为存储介质,但是不推荐使用。
InnoDB采用MVCC(多版本并发控制)支持高并发,且实现了四个标准的隔离级别(READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE),其默认级别是REPEATABLE READ, 并且通过间隙锁策略防止幻读的出现。间隙锁使得InnoDB不仅仅锁定查询涉及的行,还会对索引中的间隙进行锁定,防止幻影行插入。
InnoDB的索引结构和MySQL的其他存储引擎大不相同,InnoDB表是基于聚簇索引建立的,聚簇索引对主键查询有很高的性能。InnoDB的存储格式是平台独立的,也就是数据和索引文件可以复制到其他平台。作为事务型存储引擎,InnoDB可以通过一些机制和工具支持真正的热备份(如MySQL Enterprise Backup、XtraBackup),这是MySQL其他存储引擎不具备的特性。
MyISAM存储引擎 MyISAM是MySQL5.1以前的默认存储引擎。MyISAM不支持事务和行级锁,且崩溃后无法安全恢复。尽管如此,MyISAM也尤其价值,存在即合理。对于只读数据,依然可以选择MyISAM。
MyISAM会将表存储在数据文件和索引文件中,扩展名分别为.MYD和.MYI。MyISAM可以包含动态或静态行,MyISAM会根据表的定义来决策选用行格式。另外,MyISAM表可以存储的行记录数,一般受限于可用的磁盘空间或者操作系统单个文件的最大尺寸。
MyISAM支持表锁,读取数据时会对读到的所有表加共享锁,写入时对表加排他锁。MyISAM表可以手工或者自动执行检查和修复操作,值得注意的是这里所谓的修复和事务恢复以及崩溃恢复是两码事。执行表的修复可能导致部分数据丢失,且修复过程非常耗时。执行修复操作可以先通过CHECK TABLE test 检查表的错误,发现问题后再执行REPAIR TABLE test 进行修复。当然还可以通过myisamchk命令行工具进行检查与修复操作。
对于MyISAM压缩表,特点是只读,适合用于表数据导入后不会二次修改的场景。压缩表可以极大地减少磁盘空间占用,因此也可以减少磁盘I/O,从而提升查询性能。支持索引,但也是只读的。
Archive引擎 Archive引擎仅支持INSERT和SELECT操作。Archive还支持行级锁和专用缓冲区,可以实现高并发的插入。Archive引擎会缓存所有的写操作并利用zlib对插入的行数据进行压缩,所以比MyISAM表的磁盘I/O更少,但是每次查询操作都会全表扫描。因此,Archive表适用于日志和数据采集类系统。
Blackhole引擎 Blackhole引擎未实现存储机制,因此它会丢弃所有插入数据,不做任何保存。但是服务器会记录Blackhole表的日志,适用于复制数据到备库。这种特殊引擎可以在一些特殊的复制架构和日志审核时使用。不过并不推荐,存在不少问题。
CSV引擎 CSV引擎可以将CSV文件作为数据表来处理,但不支持索引。可以将Excel等电子表格软件中的数据存储到CSV文件,然后复制到MySQL数据目录下,就可以在MySQL中打开使用。同样,如果将数据写入到一个CSV表中,其他外部程序也能立即从表里读取CSV格式的数据。因此 此引擎适用于进行数据交换。
Federated引擎 Federated引擎是访问其他MySQL服务器的一个代理,它会创建一个到远程MySQL服务器的客户端连接,并将查询传输到远程服务器执行,然后提取或发送需要的数据。该引擎存在一些问题,默认是禁用的,了解即可。
Memory引擎 Memory表最大的特点就是重启后表结构保留,但是数据会丢失。但是其性能比MyISAM表快一个数量级,因为所有的数据都保存在内存中,不需要磁盘I/O。Memory表支持hash索引,因此查询操作非常快。Memory是表级锁,因此并发写入性能较低。
Merge引擎Merge引擎是MyISAM的一个演化分支,它是由多个MyISAM表合并而来的虚拟表。在引入分区功能后,该引擎已经弃用。
此外还有NDB集群引擎,和OLTP类引擎等第三方存储引擎,这里笔者就不详细展开介绍了,有兴趣的同学可以翻阅官方文档。
总结 MySQL提供了如此多的引擎,那么我们应该怎么选择呢?笔者的建议是遇事不决就选InnoDB。除非需要用到某些InnoDB不具备的特性,并且没有其他办法可以替代,否则都应该优选InnoDB。举个栗子,如果不考虑可扩展和高并发,且不怕数据丢失,只在意存储空间占用情况,那么MyISAM可以成为你的选择。还有就是除非万不得已,千万不要混合使用多种存储引擎,否则后面会出现一些系列难以解决的复杂问题(你把握不住)。
下期预告:MySQL事务与四大隔离级别



