MySQL 的存储引擎有哪些?它们之间有什么区别?
- 标签:后端、MySQL、数据库
🏛 业务架构师
MySQL 支持多种存储引擎,但业务上真正要对比的就是 InnoDB 与 MyISAM 这一对:
- 事务与崩溃恢复:InnoDB 支持事务、redo log 崩溃恢复;MyISAM 不支持事务,宕机后表可能损坏。交易、订单、账务这类"丢一条就是资损或客诉"的业务,MyISAM 直接出局;
- 锁粒度:InnoDB 行级锁,并发下单互不干扰;MyISAM 只有表锁,一个写操作整表排队,高并发写场景吞吐崩塌;
- 索引与外键:InnoDB 聚簇索引 + 支持外键;MyISAM 索引与数据分离、不支持外键;
- 场景定位:MyISAM 的优势仅剩结构简单、某些只读统计场景稍快,且 count(*) 无 where 时有元数据级优化。
我的选型立场很明确:交易型业务一律 InnoDB,没有例外。哪怕是日志、报表这类弱一致需求,为了统一运维体系、备份恢复流程,也继续用 InnoDB——异构引擎的运维成本远大于那点性能差异。真实教训是:早年有些老系统建表默认落成 MyISAM,一次宕机后修复表花了几个小时,从此我把"建表规范强制 ENGINE=InnoDB"写进了公司级研发规范。存储引擎选型是资损和可用性问题,不是性能偏好问题。
🏗 系统架构师
MySQL 支持多种存储引擎,插件式架构,实际生产里 99% 的场景是 InnoDB,我重点对比它和 MyISAM:
- 事务:InnoDB 支持 ACID、崩溃恢复(redo/undo);MyISAM 不支持,宕机后表可能损坏;
- 锁粒度:InnoDB 行级锁,并发写能力强;MyISAM 只有表锁,写互斥读,高并发下吞吐塌方;
- 外键、MVCC、聚簇索引:只有 InnoDB 有;MyISAM 索引和数据分开存(非聚簇),主键查询多一次寻址;
- MyISAM 的历史优势:结构简单、全表 count 无需扫行(存了元数据计数)、读密集场景快——但这些优势被缓存层(Redis)取代后就没有存在价值了。
此外还有 Memory(重启丢数据,适合临时表)、Archive(高压缩比日志归档)等。
从架构演进看,5.5 之后默认引擎切到 InnoDB 是必然:互联网业务都是读多写也多、要求高可用,表锁引擎无法水平承接并发,选型上我无脑 InnoDB,差异化的读写需求交给缓存和只读副本解决。
💻 全栈开发专家
用 SHOW ENGINES 能看到一堆,实际生产就两种:
| 维度 | InnoDB(默认) | MyISAM |
|---|---|---|
| 事务 | 支持 | 不支持 |
| 锁 | 行锁 | 只有表锁 |
| 外键 | 支持 | 不支持 |
| 索引 | 聚簇索引 | 非聚簇 |
| 崩溃恢复 | redo log 安全恢复 | 基本没有,易坏表 |
我的实战观点:99% 的业务表都应该用 InnoDB。MyISAM 唯一的优势是表级元数据让 COUNT(*)(无 where)飞快,以及全文索引——现在都能被替代:计数用缓存/计数表,全文用 ES。
真踩过的坑:接手过一个老系统日志表是 MyISAM,主机异常重启后表损坏,REPAIR TABLE 跑了半小时还丢数据。另外还有 Memory 引擎(重启数据没了,只适合临时表)和 8.0 的 TempTable 引擎(内部临时表用)。历史遗留系统排查时先 SHOW TABLE STATUS 看引擎是不是被降级了。