MySQL · 存储引擎

简介

MySQL 数据库区别于其他数据库的最重要的一个特点就是其插件式的表存储引擎。

我们知道关系型数据库的数据是存在表里的,可以将表理解为由行和列组成的表格,类似于 Excel 的电子表格的形式,每个表格就是一个数据。表在存储数据的同时,还要组织数据的存储结构,而这些数据的组织结构就是由存储引擎决定的。简单来说,存储引擎的作用就是规定了数据的存储结构,由实际业务决定

插件式存储引擎的好处是,每个存储引擎都有各自的特点,可以根据具体的应用建立不同的存储引擎表,这也是 MySQL 的强大之处。

需要特别注意的是,存储引擎是基于表的,而不是数据库。

MySQL 存储引擎

MySQL 支持多种存储引擎,可以通过 show engines 语句来查看。日常开发中用到最多的存储引擎是 InnoDB 与 MyISAM 两种,都是以插件的形式集成在数据库中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+

InnoDB

InnoDB 存储引擎支持事务,其设计目标主要面向 OLTP 的应用。特点是行锁设计、支持外键。从 MySQL 5.5.8 版本开始,InnoDB 是 MySQL 默认的存储引擎。

InnoDB 通过使用多版本并发控制 MVCC 来获得高并发性,并且实现了 SQL 标准的 4 种隔离级别,默认为 REPEATABLE 级别。同时,使用一种被称为 next-key-locking 的策略来避免幻读的产生。除此之外,InnoDB 存储引擎还提供了插入缓冲(insert buffer)、二次写(double write)、自适应哈希索引(adaptive hash index)、预读(read ahead)等高性能和高可用功能。

对于表中数据的存储,InnoDB 存储引擎采用了聚集(cluster)的方式,因此每张表的存储都是按照主键的顺序进行存放。如果没有显式地在表定义时指定主键,InnoDB 存储引擎会为每一行生成一个 6 字节的 ROWID,并以此作为主键。

MyISAM

MyISAM 存储引擎不支持事务、表锁设计,支持全文索引,主要面向一些 OLAP 应用。在 MySQL 5.5.8 之前,MyISAM 是默认的存储引擎。此外,MyISAM 存储引擎的另一个与众不同的地方在它的缓冲池只缓存(cache)索引文件,而不缓冲数据文件,这一点和大多数数据库都非常不同。

MyISAM 存储引擎表由 MYD 和 MYI 组成,MYD 用来存放数据文件,MYI 用来存放索引文件。

NDB

NDB 存储引擎是一个集群存储引擎,类似于 Oracle 的 RAC 集群。其特点是数据全部存放在内存中,因此主键查找的速度极快,并且通过添加 NDB 数据存储节点可以线性地提高数据库性能,是高可用、高性能的集群系统。

关于 NDB 存储引擎,有一个问题值得注意,那就是 NDB 存储引擎的连接操作 JOIN 是在 MySQL 数据库层完成的,而不是在存储引擎层完成。这意味着,复杂的连接操作需要巨大的网络开销,因此查询速度很慢。

Memory

Memory 存储引擎将表中数据存放在内存中,如果数据库重启或发生崩溃,表中数据都将消失。它非常适合用于存储临时数据的临时表。Memory 存储引擎默认使用哈希索引,而不是 B+ 树索引。

虽然 Memory 存储引擎速度非常快,但在使用上还是有一定的限制。比如只支持表锁,并发性能较差,并且不支持 TEXT 和 BLOB 列类型,最重要的是,存储变长字段 varchar 时是按照定长字段 char 方式进行,因此会浪费内存。

Archive

Archive 存储引擎只支持 INSERT 和 SELECT 操作,使用 zlib 算法将数据行进行压缩后存储,压缩比一般可达 1:10,Archive 存储引擎非常适合存储归档数据,如日志信息。其设计目标主要是提供高速的插入和压缩功能。

InnoDB 与 MyISAM 对比

  • 「事务」: InnoDB 是事务型的,可以使用 Commit 和 Rollback 语句,MyISAM 不支持事务。
  • 「并发」: MyISAM 只支持表级锁,而 InnoDB 还支持行级锁。
  • 「外键」: InnoDB 支持外键。
  • 「备份」: InnoDB 支持在线热备份。
  • 「崩溃恢复」: MyISAM 崩溃后发生损坏的概率比 InnoDB 高很多,而且恢复的速度也更慢。
  • 「其它特性」: MyISAM 支持压缩表和空间数据索引。