以下是 MyISAM vs InnoDB 的全面对比表,可以帮助你系统掌握两者在功能、性能、应用场景等方面的区别👇
分类 | InnoDB | MyISAM |
---|---|---|
✅ 默认引擎 | ✅ 是(MySQL 5.5 之后默认) | ❌ 否(MySQL 5.5 之前默认) |
📦 存储结构 | 表结构 .frm + 数据+索引 .ibd 或共享表空间 | .frm + .MYD (数据)+ .MYI (索引) |
📌 索引类型 | 聚簇索引(主键索引的叶子节点存整行数据) | 非聚簇索引(叶子节点存物理地址) |
🔐 锁机制 | 行级锁 + 表级锁 + 间隙锁(支持事务隔离) | 表级锁(写锁会阻塞所有读) |
🔄 事务支持 | ✅ 支持事务、回滚、崩溃恢复 | ❌ 不支持事务 |
💾 崩溃恢复 | ✅ 支持 crash-safe(redo log + undo log) | ❌ 崩溃容易导致数据损坏 |
🚦 并发性能 | 高(行级锁 + MVCC) | 低(写时锁整个表) |
🧠 MVCC 支持 | ✅ 支持 | ❌ 不支持 |
🔍 全文索引 | ✅ 从 MySQL 5.6 开始支持 | ✅ 早期支持(MySQL 5.5 及以前) |
🔑 外键 | ✅ 支持 | ❌ 不支持 |
📊 适合场景 | 写多读多、有事务要求、强一致性 | 读多写少、对事务不敏感、只读数据 |
⚠️ 幻读控制 | ✅ 有隔离级别控制(如 RR) | ❌ 不支持,不能避免幻读 |
📈 查询速度 | 二级索引需要回表查询 | 读取索引后直接定位数据文件,纯读速度快 |
🛠️ 工具兼容 | ✅ mydumper、xtrabackup 等全面支持 | ❌ 一些工具不兼容,如 xtrabackup 不支持备份 |
索引和数据存储方式
“MyISAM 索引和数据分离,而 InnoDB 索引和数据在一起”
🧱 一、MyISAM:索引和数据分开存储
✅ 文件结构回顾
假设有个 MyISAM 表 user
,会生成三个文件:
文件类型 | 文件名 | 内容 |
---|---|---|
表结构 | user.frm | 表定义 |
数据文件 | user.MYD | 存储数据本体 |
索引文件 | user.MYI | 存储所有索引 |
✅ 索引结构
- MyISAM 的索引是典型的 B+ 树结构
- 叶子节点存储的是数据的物理地址(指针),不是数据本身
- 查数据过程是“两步走”:
- 先查索引定位数据文件的位置
- 再去
.MYD
文件里根据地址把数据读出来
📌 举个例子:
执行:
SELECT name FROM users WHERE id = 1001;
流程是:
- 在
.MYI
文件(索引文件)里找到 id=1001 的地址(比如偏移量 2000) - 去
.MYD
数据文件偏移 2000 读取整行数据 - 取出 name 字段返回
所以:MyISAM 的索引叶子节点只保存地址,不保存数据本身
🌳 二、InnoDB:聚簇索引,索引和数据存一起
InnoDB 的主键索引是 Clustered Index(聚簇索引):
✅ 聚簇索引结构
- InnoDB 也是 B+ 树结构
- 主键索引的叶子节点就直接存储了整行数据
- 所以:
- 查主键时:一步到位
- 查二级索引时:还要再回主键索引(称为“回表”)
📌 举个例子:
表结构:
CREATE TABLE users (id INT PRIMARY KEY,name VARCHAR(100),age INT
) ENGINE=InnoDB;
主键查询:
SELECT * FROM users WHERE id = 1;
- 直接在主键 B+ 树上查到
id=1
的叶子节点 - 叶子节点中就包含了整行
id, name, age
,不需要“跳出去”查数据
二级索引查询:
SELECT name FROM users WHERE age = 20;
- age 是二级索引
- 先用二级索引找到对应的主键 id
- 然后去主键聚簇索引里“回表”查整行数据
🔍 总结对比图
特性 | MyISAM | InnoDB |
---|---|---|
索引类型 | B+ 树 | B+ 树 |
主键索引叶子节点 | 存储数据地址 | 存储整行数据 |
数据与索引存储位置 | 分离(MYD/MYI) | 一体(聚簇索引) |
主键查找效率 | 要跳两次(查地址+查数据) | 一次查找,效率更高 |
二级索引 | 也存地址 | 存主键值,需要“回表” |
📌 为什么 InnoDB 用聚簇索引?
- 让主键查询更快:常见的主键查找一跳就搞定
- 支持事务和行锁:聚簇索引是实现 MVCC 的基础
- 减少磁盘 I/O:数据和主键放一起,避免多次跳转
✅ MyISAM 的索引和数据是分离的(索引指向数据地址)
✅ InnoDB 的主键索引和数据是在一起的(聚簇索引)
这个差异对性能、事务、锁机制都有很大影响,也是 InnoDB 被默认采用的重要原因之一。
🔍 总结一句话:
- InnoDB:现代数据库首选,适合事务型、并发写多、强一致场景。
- MyISAM:轻量、只读性能高,但不支持事务,不 crash-safe,不建议新项目使用。