InnoDB 支持 ACID 事务、行锁、崩溃自动恢复及持久化 AUTO_INCREMENT,MyISAM 仅支持表锁、无事务、崩溃易丢数据且重启可能重置自增主键,新建项目应优先选 InnoDB。
MyISAM 不支持事务,InnoDB 支持 ACID 事务
如果你的应用需要回滚、提交或崩溃恢复能力,InnoDB 是唯一合理选择。MyISAM 完全忽略事务语义——哪怕你写了 BEGIN 或 ROLLBACK,它也当作普通语句执行,不报错但也不生效。
常见踩坑场景:
- 误以为
INSERT ... SELECT在 MyISAM 中能原子执行,实际中途失败会导致部分写入且无法回退 - 用 MyISAM 做订单表,支付成功后更新状态失败,无法通过事务保证“扣款+改状态”一致性
-
autocommit=0对 MyISAM 表完全无效,COMMIT和ROLLBACK被静默忽略
MyISAM 表锁 vs InnoDB 行锁
MyISAM 对整张表加锁:一个 UPDATE 正在执行,所有其他对这张表的 SELECT、INSERT 都得排队等它完成。InnoDB 默认按索引行加锁(主键或唯一索引),并发能力高得多。
但注意几个关键细节:
- InnoDB 的“行锁”不是万能的:没走索引的
WHERE条件会升级为表锁(例如UPDATE t SET x=1 WHERE y='abc',而y没索引) - MyISAM 的
CONCURRENT INSERT只在表尾追加时有效,且不能有空洞(被DELETE过的行位置不复用) - 高并发写场景下,MyISAM 的锁争用会直接拖垮 QPS,而 InnoDB 即使锁冲突也会尝试等待而非立即失败
崩溃恢复能力差异极大
MyISAM 崩溃后靠 myisamchk 修复,但可能丢数据(尤其写到一半断电),且修复过程需锁表。InnoDB 依赖重做日志(ib_logfile)和双写缓冲(doublewrite),能保证已提交事务不丢失,启动时自动前滚恢复。