提起数据库DataBase,大家肯定不陌生。尽管现在NoSql数据库发展如火如荼,很是吸引大家的眼球;但是不可否认的是关系型数据库依然在某些应用场景中占据主要地位,不可动摇。
数据库中的Mysql数据库,大家肯定也不陌生。作为开源(现在被收购,开源前景未知)的成功典型,Mysql为企业节省了巨大的成本,否则只是数据库的使用成本就会使开销增加许多。笔者所在的公司使用的也是Mysql数据库。
在熟悉存储引擎之前,我们先了解下Mysql的体系结构,这个在使用引擎时也是很重要的一环。
我们先看下Mysql的体系架构图:
这个体系结构比较清楚,能够比较清晰的看出有如下几个部分组成:
组件代码
Connectors:连接组件
Enterprise Management Service & Utilities:管理服务和组件
Connection Pool:连接池组件
SQL interface:SQL接口组件
Parser:查询分析器组件
Optimizer:优化器组件
Caches & Buffers:缓存组件
Pluggable Storage Engines:插拔式存储引擎
File System:文件系统
File & Logs:存储文件和日志
从图中可以看出来,Mysql支持插件式的表存储引擎。Mysql提供了一些列标准的管理和服务支持,这些标准和存储引擎无关,是每个数据库本身所必须的,如SQL interface、Parser、Optimizer等;而存储引擎是底层物理结构的实现,每个开发者都可以按照自己的意愿来开发或者修改存储引擎的内容。
从体系结构图上还可以看出来,存储引擎是基于表,而不是数据库。这点一定要记牢,对于后续的说明有很大帮助。
我们打开自己的mysql客户端连接上服务器,执行如下命令:
mysql> show engines;
+------------+---------+----------------------------------------------------------------+
| Engine | Support | Comment |
+------------+---------+----------------------------------------------------------------+
| MyISAM | DEFAULT | Default engine as of MySQL 3.23 with great performance |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables |
| InnoDB | YES | Supports transactions, row-level locking, and foreign keys |
| BerkeleyDB | YES | Supports transactions and page-level locking |
| BLACKHOLE | NO | /dev/null storage engine (anything you write to it disappears) |
| EXAMPLE | NO | Example storage engine |
| ARCHIVE | NO | Archive storage engine |
| CSV | NO | CSV storage engine |
| ndbcluster | NO | Clustered, fault-tolerant, memory-based tables |
| FEDERATED | NO | Federated MySQL storage engine |
| MRG_MYISAM | YES | Collection of identical MyISAM tables |
| ISAM | NO | Obsolete storage engine |
+------------+---------+----------------------------------------------------------------+
12 rows in set (0.00 sec)
可以看到当前的Mysql官方和第三方的引擎和当前MySql所支持的存储引擎。其中MyISAM为默认存储引擎,在非Windows平台上,MyISAM为默认使用的存储引擎。不过在5.6上把InnoDB作为默认的存储引擎
Mysql数据库独有的插件式体系构架,让存储引擎有了依赖于应用的多样性。开发人员能够根据应用的不同特点,选择合适的存储引擎;如果存储引擎不能满足要求的话,还可以定制适合自己应用的存储引擎。eBay、Google、Facebook等公司都对MySql存储引擎做过改进,使其满足自己的业务特性。最为知名的是MyISAM和InnoDB存储引擎,其它的存储引擎也需要了解特性,才能在应用中选择合适的存储引擎。
下面我们来了解下这些引擎的特性,来源为官方的最新文档 http://dev.mysql.com/doc/refman/5.6/en/storage-engines.html。
MyISAM存储引擎:
MyISAM存储引擎的特性请看下图:
作为官方存储引擎,MyISAM的特点是不支持事务,表锁和全文索引。表锁限制了引擎的读写性能,在read-only 或者 read-mostly场景下性能不错,常常应用于OLAP(OnLine Analytical Processing)中,操作速度快,在非windows环境下为默认的存储的引擎,如果你创建表没有指定存储引擎的话(MySQL 5.6修改了默认存储引擎)。
MyISAM表存储在三个文件里,有表名和扩展名组成:.frm扩展名存储表格式、.MYD扩展名存储文件(MYData)、.MYI存储索引文件。
MyISAM还有一些其它的特性:如单表索引限制为64个,单索引支持列数为16,单表记录限制为2^64等,这些都是MyISAM的特性,尽管这种限制在平常应用中很少能用到。更为详细的特性请查看这里:http://dev.mysql.com/doc/refman/5.6/en/myisam-storage-engine.html
InnoDB存储引擎:
InnoDB根据其引擎特性,在面向OLTP(OnLine Transaction Processing)处理中应用广泛。其特点是支持事务、行锁设计、支持外键;并且支持类Oracle的非锁定读特性,现在在Mysql 5.6版本中作为默认的存储引擎。
InnoDB存储引擎的完整特性看下图:
事务支持(Transaction-Support)、ACID特性,支持事务提交、回滚、灾难回滚等特性,对于用户数据的保护可见一斑;Row-Level Locking和Oracle-Style非锁定读大大提升了多用户操作的并发性和性能;能根据主键优化查等,这些特性都使得InnoDB在OLTP应用中大展宏图。
InnoDB通过使用多版本并发控制(MVCC)来获得高并发性,实现了SQL标准的四种隔离级(Read Uncommitted、Read Committed、Repeatable Read、Serializable),Mysql的默认隔离级别为Repeatable Read;并且通过next-key locking的策略来避免幻读(phantom)现象的产生。更多关于InnoDB详细的特性请参考这里:http://dev.mysql.com/doc/refman/5.6/en/innodb-storage-engine.html
Memory存储引擎:
Memory存储引擎(以前知名的是HEAP),顾名思义是将所有的数据都放在内存里,能够对数据进行快速的获取。如果断电或者数据库重启或者崩溃的话,表中的数据都会消失。
Memory存储引擎的特性如下所示:
根据上图,Memory存储引擎支持的特性有限,所以其功能也有限;由于其存取速度的特性,非常适合存储临时数据的临时表。另外Memory存储引擎默认使用是哈希索引,而不是熟悉的B+结构。更多细节见这里:http://dev.mysql.com/doc/refman/5.6/en/memory-storage-engine.html
Archive存储引擎:
Archive引擎只支持insert和select操作,Mysql 5.6版本不支持索引;支持AUTO_INCREMENT属性,使用了自增属性的列会有一个索引,单独创建索引是不支持的。
正如其名所示,Archive存储引擎非常适合存储归档数据,如日志信息;引擎能够使用zlib算法压缩数据,压缩率可到1:10。Archive存储引擎使用行锁来实现高并发的插入功能,但是其本身不是安全的存储引擎,设计目标主要是提供高速的插入和压缩功能。过多细节详见:http://dev.mysql.com/doc/refman/5.6/en/archive-storage-engine.html
CSV存储引擎:
CSV存储引擎通过文件来保存数据,其中的行记录用comma分割。CSV引擎支持以CSV格式导入和导出数据。由于使用Comma分割数据,所以CSV引擎不支持索引。一般来说,在平时操作InnoDB中的数据时,可以通过CSV表来保存数据,这样可以在数据库之间导数据时用到这一点。更多细节见:http://dev.mysql.com/doc/refman/5.6/en/csv-storage-engine.html
Blackhole存储引擎:
Blackhole存储引擎类似于Linux上的/dev/null,能够插入数据但是不保存数据。对设定为Blackhole引擎的表查询总是返回空集。如果想激活Blackhole存储引擎的话,在Mysql源码编译选型中添加-DWITH_BLACKHOLE_STORAGE_ENGINE激活Blackhole存储引擎。更多细节见http://dev.mysql.com/doc/refman/5.6/en/blackhole-storage-engine.html
Example存储引擎:
Example存储引擎什么事都不干,其目的是作为Mysql源码的示例展示如何构建新的存储引擎。对于使用者来说,这个引擎只是个幌子,但是对于开发者来说,Example存储引擎的源码算是最为亲切的了。
Federated存储引擎:
Federated存储引擎本身并不保存数据,它只是指向一台远程的Mysql数据库服务器上的表。对本地Feterated存储引擎表,本地Server会自动从远端Mysql上获取数据,在本地表里面上并不保存任何数据。
Maria存储引擎:
Maria存储引擎是新开发中的存储引擎,其设计目标是用来取代原有的MyISAM存储引擎,成为Mysql的默认存储引擎,也可以看做是MyISAM的后续版本,其主要特点包括:缓存数据和索引文件、行锁设计、提供MVCC功能、支持事务和非事务安全的选项支持,更好的处理BLOB类型支持。
目前主要使用在MariaDB中,其开发者是Michael Widenius,Mysql的创始人之一。在MariaDB的官网上有关于MariaDB和Mysql的比较,比较结果参考这里:https://mariadb.org/en/about/
选择合适的存储引擎对于应用来说至关重要,而了解存储引擎的特性对于选择合适的引擎同样同样重要。因此了解Mysql存储引擎的特性,在工作中能有事半功倍的效果,能够让你明白在开发应用中,哪些是能够通过数据库控制来完成,而哪些又是必须通过自己写代码控制才能完成的功能。
本节Mysql存储引擎的内容到此结束。