InnoDB 与 MyISAM 核心区别
概述
InnoDB 和 MyISAM 是 MySQL 最经典的两个存储引擎。InnoDB 在 MySQL 5.5.5 之后成为默认引擎。理解两者的区别是 MySQL 面试的必考题。
核心区别总览
graph TD
subgraph InnoDB[InnoDB - OLTP首选]
A1[事务 ✅]
A2[行级锁 ✅]
A3[外键约束 ✅]
A4[崩溃恢复 ✅]
A5[ACID兼容 ✅]
end
subgraph MyISAM[MyISAM - 只读/日志]
B1[无事务 ❌]
B2[表级锁]
B3[无外键 ❌]
B4[崩溃丢失数据]
B5[全文索引优势]
end
详细对比表
| 特性 | InnoDB | MyISAM |
|---|---|---|
| 事务支持 | ✅ 支持(ACID) | ❌ 不支持 |
| 锁粒度 | 行级锁 | 表级锁 |
| 外键 | ✅ 支持 | ❌ 不支持 |
| 崩溃恢复 | ✅ redo log 保证 | ❌ 可能丢失数据 |
| MVCC | ✅ 支持 | ❌ 不支持 |
| 全文索引 | 支持(8.0+) | ✅ 原生支持 |
| COUNT(*) | 需要扫描(有优化) | ✅ 直接返回(单独存储) |
| 聚簇索引 | ✅ 是 | ❌ 不是(堆表) |
| 缓存 | Buffer Pool 缓存数据和索引 | Key Cache 只缓存索引 |
| 数据文件 | .ibd(数据和索引一起) | .MYD(数据)/ .MYI(索引) |
| 压缩 | ✅ 支持 | ✅ 支持 |
| 空间利用 | 较高 | 较低 |
| 并发性能 | ✅ 高(行锁) | ❌ 低(表锁) |
关键特性深度解读
1. 事务:InnoDB 的护城河
-- InnoDB 典型事务操作
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
-- 如果中间崩溃,InnoDB 通过 redo log 保证数据一致性
-- MyISAM 没有事务,每个语句自动提交
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
-- 如果此时崩溃,第一条可能成功,第二条没执行,数据不一致!
2. 锁:高并发的关键
sequenceDiagram
participant T1 as 事务1
participant T2 as 事务2
participant Inno as InnoDB
participant Myi as MyISAM
Note over T1,Myi: InnoDB行锁
T1->>Inno: UPDATE t SET x=1 WHERE id=1
Inno->>Inno: 锁定id=1这一行
T2->>Inno: UPDATE t SET x=2 WHERE id=2
Inno->>Inno: 可以同时执行 ✅
Note over T1,Myi: MyISAM表锁
T1->>Myi: UPDATE t SET x=1 WHERE id=1
Myi->>Myi: 锁定整张表
T2->>Myi: UPDATE t SET x=2 WHERE id=2
Myi-->>T2: ❌ 等待T1释放表锁
3. COUNT(*) 性能差异
-- MyISAM 秒出结果(单独存储行数)
SELECT COUNT(*) FROM big_table; -- 0.001秒
-- InnoDB 需要扫描索引
SELECT COUNT(*) FROM big_table; -- 可能需要几秒
原因:MyISAM 单独维护了表的总行数,InnoDB 因为支持 MVCC,不同事务看到不同版本,无法缓存总行数。
4. 文件结构
# MyISAM 三个文件
table.frm # 表结构定义
table.MYD # 数据文件(MyData)
table.MYI # 索引文件(MyIndex)
# InnoDB 文件(取决于配置)
table.frm # 表结构定义(8.0前)
table.ibd # 数据和索引(每个表独立)
ibdata1 # 系统表空间(共享)
5. 崩溃恢复
-- MyISAM 崩溃后
CHECK TABLE t; -- 检查表完整性
REPAIR TABLE t; -- 修复表(可能丢数据)
-- InnoDB 崩溃后
-- 自动恢复!通过 redo log + undo log 恢复到一致状态
性能测试对比
| 场景 | InnoDB | MyISAM | 说明 |
|---|---|---|---|
| 大量 SELECT | 略慢 | 快 | MyISAM 索引缓存更快 |
| 大量 INSERT | 快 | 快 | 差异不大 |
| 大量 UPDATE | ✅ 快 | ❌ 极慢 | 表锁是瓶颈 |
| 混合读写 | ✅ 高并发 | 极差 | 表锁导致写阻塞读 |
| 崩溃恢复 | ✅ 自动恢复 | ❌ 可能损坏 |
面试要点
- 最核心区别:InnoDB 支持事务和行级锁,MyISAM 不支持
- 一句话选型:OLTP 用 InnoDB,只读/日志类场景可以用 MyISAM
- COUNT(*):MyISAM 快但牺牲了事务一致性
- 8.0 变化:系统表也变成了 InnoDB,MyISAM 进一步被边缘化
一句话总结:InnoDB 是为”并发+可靠”而生的,MyISAM 是为”简单+快速”而生的。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容