开创新时代的 MySQL8
新时代已经来临,不用纠结,不用犹豫,使用 InnoDB 吧。
MyISAM 存储引擎已经有了 20 年的历史,在 1995 年时,MyISAM 是 MySQL 唯一的存储引擎,服务了 20 多年,即将退居二线。
MySQL 5.7 中仍然使用了 MyISAM 作为系统表的存储引擎,MySQL 8.0 引入了新的数据字典,系统表便不再使用 MyISAM,而且 MySQL 8.0 中 MyISAM 被极大的限制了使用范围,例如不允许拷贝 MyISAM 表到正在运行的 MySQL server 中
MySQL 8.0 中仅支持创建一个 engine=MyISAM 的表,然后像以前一样工作
MyISAM 的退休是因为他固有一些弱项(例如 不支持事务、表级锁、没有崩溃恢复),而且他的优点已经逐渐被 InnoDB 实现了,例如:
| 特点 | 开始支持的版本 |
|---|---|
| 全文索引 | 5.6 |
| 表空间优化 | 5.6 |
| GIS空间索引 | 5.7 |
| 表最新更新时间 | 5.7 |
| 临时表优化 | 5.7 |
高效的count(*) |
5.7 |
两者之前的差异
| 对比项 | InnoDB | MyISAM |
|---|---|---|
| 事务 | 支持,具有提交、回滚和崩溃恢复能力 | 不支持 |
| 行级锁 | 支持 | 不支持 |
| 外键 | 支持外键完整性约束 | 不支持 |
| 全文索引 | MySQL 5.6 版本之后 InnoDB 存储引擎开始支持全文索引,5.7版本之后通过使用 ngram 插件开始支持中文 |
支持 |
| 缓存 | 在主内存中维护自己的内存缓冲池来缓存数据和索引,对内存要求较高,内存大小对性能有决定性影响 | 只缓存索引 |
| 表空间 | 大 | 小 |
| 存储限制 | 64TB | 256TB |
| 数据库文件 | 数据和索引在一个文件(篇幅有限,表格后面详细说明) | .frm 用于存储表的定义;.MYD 用于存放数据;.MYI 用于存放表索引 |
| 主键 | 必须(如果没有显式指定,MySQL会自动选择或生成) | 非必须 |
| 主索引(主键上的索引) | 主索引使用的是聚集索引,索引文件就是数据文件,其叶节点的 data域 存放的是行数据 |
MyISAM 的主索引与辅助索引在结构上完全一样(没有主键则没有主索引) |
| 辅助索引(非聚集索引) | data域 记录对应的行数据的主键,通过主键的值在主索引中查找行数据 |
data域 记录行数据的标识符 |
| 索引长度 | 每个列的长度不能大于767 bytes;所有组成索引列的长度和不能大于3072 bytes | 每个列的长度不能大于1000 bytes,所有组成索引列的长度和不能大于1000 bytes |
| 高效的 COUNT(*) | MySQL5.7起支持,在此之前需要扫描全表 | 计数器记录,不需要扫描全表。有 where 条件之后 MyISAM 和 InnoDB 一样都需要扫描符合条件的记录数) |
| 插入效率 | 需要花费开销在维护完整性和维持事务上,效率相对低,但是 InnoDB 支持多线程并发插入 |
单线程效率更高,但是 MyISAM 是表锁,不支持并发插入 |
InnoDB 的数据库文件结构
MySQL8之前,InnoDB的表结构存储在表名.frm文件中,数据和索引存储在表空间中MySQL8起,InnoDB的表结构和表数据、索引,都存储在表空间中
表空间有两种形式:
共享表空间
所有表的行数据和索引数据(
MySQL8起包括表结构)都保存在一个表空间里,一个表空间可以有多个文件,通过innodb_data_file_path和innodb_data_home_dir参数设置共享表空间的名字和位置,一般共享表空间的名字叫ibdata1-n。多表空间
通过
innodb_file_per_table参数设置是否启用多表空间。启用后,每个表都有一个表空间文件用于存储每个表的数据和索引(MySQL8起包括表结构),文件名以表名开头,以.ibd为扩展名。启用多表空间并不意味着不再需要共享表空间了,每张表的表空间内存放的只是数据、索引和插入缓冲(
MySQL8起包括表结构),其他类的数据,如撤销(Undo)信息、系统事务信息、二次写缓冲(double write buffer)等还是存放在原来的共享表空间内
存储引擎的选择
- InnoDB:当需要提供回滚和崩溃恢复能力的事务安全能力,并要求实现并发控制时,只有
InnoDB具有事务处理能力。
- MyISAM:如果数据表主要用来插入和查询,MyISAM 能提供更好的处理效率
Memory:数据存在内存中。如果只是临时存储数据,数据量不大,且不要求较高的数据安全性,
Memory更合适Archive:如果只有
INSERT和SELECT操作,Archive支持高并发的插入操作,非常适合存储归档数据