InnoDB
InnoDB 是 MySQL 的默认事务型引擎,用来处理大量短期事务。InnoDB 的性能和自动崩溃恢复特性使 得它在非事务型存储需求中也很流行,除非有特别原因否则应该优先考虑 InnoDB。
InnoDB 的数据存储在表空间中,表空间由一系列数据文件组成。MySQL4.1 后 InnoDB 可以将每个表 的数据和索引放在单独的文件中。
InnoDB 采用 MVCC 来支持高并发,并且实现了四个标准的隔离级别。其默认级别是 REPEATABLE READ, 并通过间隙锁策略防止幻读,间隙锁使 InnoDB 不仅仅锁定查询涉及的行,还会对索引中的间隙进行锁定 防止幻行的插入。
InnoDB 表是基于聚簇索引建立的,InnoDB 的索引结构和其他存储引擎有很大不同,聚簇索引对主键查询 有很高的性能,不过它的二级索引中必须包含主键列,所以如果主键很大的话其他所有索引都会很大, 因此如果表上索引较多的话主键应当尽可能小。
InnoDB 的存储格式是平***立的,可以将数据和索引文件从一个平台复制到另一个平台。
InnoDB 内部做了很多优化,包括从磁盘读取数据时采用的可预测性预读,能够自动在内存中创建加速 读操作的自适应哈希索引,以及能够加速插入操作的插入缓冲区等。
MyISAM 和 InnoDB 的区别
事务
InnoDB 支持事务,MyISAM 不支持事务。这是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;
外键
InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败;
锁粒度
InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁。一个更新语句会锁住整张表, 导致其他查询和更新都会被阻塞,因此并发访问受限。这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;
索引类型
InnoDB 是聚集索引,MyISAM 是非聚集索引。聚簇索引的文件存放在主键索引的叶子节点上, 因此 InnoDB 必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键, 然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。
行数
InnoDB 不保存表的具体行数,执行 select count(*) from table 时需要全表扫描。 而MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
存储引擎相关的命令
查看 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 |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
从上图我们可以查看出 MySQL 当前默认的存储引擎是 InnoDB,并且在 5.7 后的版本所有的存储引擎中只有 InnoDB 是事务性存储引擎,也就是说只有 InnoDB 支持事务。
查看 MySQL 当前默认的存储引擎
show variables like '%storage_engine%';
+----------------------------------+--------+
| Variable_name | Value |
+----------------------------------+--------+
| default_storage_engine | InnoDB |
| default_tmp_storage_engine | InnoDB |
| disabled_storage_engines | |
| internal_tmp_disk_storage_engine | InnoDB |
+----------------------------------+--------+
参考资料
文档信息
- 本文作者:Bob.Zhu
- 本文链接:https://adolphor.github.io/2021/05/20/mysql-engines/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)