innodb 是 mysql 默认且首选引擎,因其支持事务、行级锁、外键和崩溃恢复,保障数据一致性;myisam 仅适用于特定只读场景但存在不支持事务、表锁和崩溃需手动修复等风险;memory 引擎仅适合临时计算。

MySQL 默认用 InnoDB,绝大多数业务场景直接选它就对了;只有明确需要全文索引+高并发读、或极低延迟的只读归档场景,才考虑 MyISAM 或 Archive——但后者几乎不用在主业务表中。
为什么 InnoDB 是默认且首选
InnoDB 支持事务、行级锁、外键、崩溃恢复,这些不是“锦上添花”,而是现代 Web 应用数据一致性的底线。比如一个转账操作涉及两条 UPDATE,若用 MyISAM,中途失败会导致数据不一致,且无法回滚。
- 写多或读写混合场景下,
InnoDB的行锁比MyISAM的表锁吞吐高得多 -
InnoDB的 MVCC 机制让普通SELECT不加锁,读性能不因写阻塞 - 即使你暂时没用事务,也建议开启(
autocommit=1是默认),为后续扩展留余地 -
InnoDB表空间可在线收缩(ALTER TABLE ... ROW_FORMAT=COMPACT配合OPTIMIZE TABLE),MyISAM的.MYD文件一旦膨胀很难回收
MyISAM 仅剩的适用场景和风险
MyISAM 现在基本只用于:历史日志表(如用户点击流)、报表宽表(纯 SELECT + FULLTEXT 搜索)、或遗留系统迁移过渡。但它不支持事务,INSERT 过程中整表锁定,且崩溃后需手动 REPAIR TABLE。
- 如果真要用
MyISAM,务必关闭delay_key_write(默认 ON),否则断电可能丢索引数据 -
MyISAM的COUNT(*)虽快,但结果不准(不加WHERE时依赖表头缓存,非实时统计) - 5.7+ 版本已移除
MyISAM全文索引的布尔模式部分功能,InnoDB的FULLTEXT已足够覆盖
别碰 Memory 引擎,除非你清楚后果
Memory 引擎把表存在 RAM 里,重启即空——它不是缓存方案,而是临时计算容器。常见误用是拿它存“热点配置”或“会话信息”,结果服务重启后全丢。
- 只适合生命周期明确的中间结果,例如
CREATE TEMPORARY TABLE t ENGINE=MEMORY SELECT ... - 不支持
TEXT/BLOB类型,VARCHAR实际按CHAR存储,内存浪费严重 - 所有连接共用同一份内存池(
max_heap_table_size),一张大表可能挤爆其他查询
架构设计时真正该关注的引擎之外的事
比起纠结引擎,更关键的是:字段类型是否精简(比如用 TINYINT 代替 INT 存状态)、索引是否覆盖高频 WHERE 条件、是否避免 SELECT *、分库分表时机是否合理。引擎只是底座,上面的数据访问模式才决定性能上限。
一个容易被忽略的点:InnoDB 的聚簇索引特性意味着主键选择直接影响所有二级索引大小——如果用 UUID 做主键,每个二级索引的叶子节点都要存完整 16 字节 UUID,而自增 BIGINT 只要 8 字节,长期看 IO 和内存开销差异明显。










