MySQL 的 MyISAM 与 InnoDB 存储引擎的核心区别

一、简介

MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力,此种技术称为存储引擎,MySQL 支持多种存储引擎,其中目前应用最广泛的是 InnoDB 和 MyISAM 两种。

存储引擎决定了数据如何存储在磁盘上,以及如何被访问。它提供了数据的存储机制、索引技巧、锁定水平,并最终提供不同的功能和能力。具体的数据库里面的输入,如何存储到物理的数据文件里面,是由存储引擎来实现的。

在 MySQL5.5 之后默认存储引擎是 InnoDB,在之前是 MyISAM。

二、MyISAM 存储引擎

1、引擎特点

  • 不支持事务

  • 表级锁定

  • 读写相互阻塞,写入不能读,读时不能写

  • 只缓存索引

  • 不支持外键约束

  • 不支持聚簇索引

  • 支持全文索引

  • 读取数据较快,占用资源较少

  • 不支持MVCC(多版本并发控制机制)高并发

  • 崩溃恢复性较差

  • MySQL5.5.5 前默认的数据库引擎

2、适用场景

  • 读多写少的业务(或者只读的业务)

  • 不需要事务支持的业务(比如转账,充值这种业务就不行)

  • 并发访问低的业务

  • 对数据一致性要求不高的业务

  • 表较小(可以接受长时间进行修复操作)

三、InnoDB 存储引擎

1、引擎特点

  • 支持事务,适合处理大量短期事务

  • 行级锁定

  • 读写阻塞与事务隔离级别相关

  • 可缓存数据和索引

  • 支持聚簇索引

  • 崩溃恢复性更好

  • 支持MVCC高并发

  • 支持表分区,支持表空间

  • 从MySQL5.5 后支持全文索引

  • 从MySQL5.5.5 开始为默认的数据库引擎

2、适用场景

  • 数据读写都较为频繁的业务

  • 需要事务支持的业务

  • 对并发要求较高的业务

  • 对数据一致性要求较高的业务

四、核心区别

对比维度 MyISAM InnoDB
事务支持 不支持事务,属于非事务型引擎 支持 ACID 事务,提供事务提交、回滚功能
锁机制 仅支持表级锁(Table-level Lock) 支持行级锁(Row-level Lock)+ 表级锁,默认行锁
索引结构 非聚簇索引,索引与数据分离,索引叶子节点存数据地址 聚簇索引,主键索引叶子节点直接存完整数据,辅助索引存主键值
崩溃恢复 不支持崩溃后自动恢复,依赖手动修复(如 myisamchk) 支持崩溃恢复,通过redo log和undo log保障数据一致性
外键支持 不支持外键约束 支持外键约束
表空间 每个表对应三个文件(.frm/.MYD/.MYI) 支持共享表空间(ibdata1)和独立表空间(.ibd)
并发性能 低,表锁导致高并发写入时冲突严重 高,行锁仅锁定修改行,适合高并发读写场景
全文索引 原生支持全文索引(MySQL 5.6 前) MySQL 5.6 及以后支持全文索引
数据缓存 仅缓存索引,不缓存数据(依赖 OS 缓存) 缓存索引和数据(InnoDB Buffer Pool)

五、关键差异细节对比

1、事务支持

MyISAM:无事务概念,执行INSERT/UPDATE/DELETE时直接写入磁盘,一旦操作中断,数据可能部分写入,无法回滚。

InnoDB:通过事务日志(redo/undo log)实现 ACID 特性,即使中途崩溃,重启后可通过日志恢复未完成的事务,保证数据一致性。

2、锁机制

MyISAM(表锁):操作一张表时锁定整个表,读操作加共享锁(多个读可并发),写操作加排他锁(阻塞所有读写)。适合读多写少场景,写入频繁时会出现严重锁等待。

InnoDB(行锁):仅锁定需要修改的行,不同行的读写操作可并发执行,大幅提升高并发场景下的吞吐量。但行锁基于索引实现,若查询未命中索引,会升级为表锁。

3、索引结构

MyISAM(非聚簇索引):索引文件(.MYI)与数据文件(.MYD)分离。索引叶子节点存储的是数据在.MYD 文件中的物理地址,查询时需先查索引获取地址,再去数据文件取数据(两次 IO)。

InnoDB(聚簇索引):主键索引与数据融合,叶子节点直接存储完整数据行(一次 IO 即可获取数据)。辅助索引叶子节点存储主键值,查询时需先通过辅助索引找到主键,再回表查主键索引获取数据(回表操作)。

4. 崩溃恢复

MyISAM:无崩溃恢复机制,若数据库意外宕机,可能导致表结构损坏,需通过myisamchk工具手动修复,修复过程可能丢失数据。

InnoDB:依赖 redo log(记录已执行的修改操作)和 undo log(记录修改前的状态)。宕机后重启时,先通过 redo log 恢复已提交但未写入磁盘的数据,再通过 undo log 回滚未提交的事务,确保数据一致性。

五、开发中的选择建议

1. 优先选择 InnoDB 的场景

  • 需要事务支持的场景:如电商订单、支付系统、金融交易等,需保证数据一致性,避免出现订单重复创建、支付状态异常等问题。

  • 高并发读写场景:如社交平台消息、商品库存修改、用户高频操作等,行锁机制可减少并发冲突,提升系统吞吐量。

  • 需要外键约束的场景:如多表关联(订单表与用户表、商品表),通过外键保证数据完整性,避免脏数据。

  • 对数据安全性要求高的场景:如核心业务数据,需依赖崩溃恢复机制保障数据不丢失、不损坏。

2. 可选 MyISAM 的场景(极少)

  • 只读或写极少的场景:如静态数据报表、日志归档表、历史数据查询表,表锁对性能影响小。

  • 需要极致读性能的简单查询场景:如单表高频查询(无关联、无复杂条件)。

  • 旧系统兼容场景:部分遗留系统基于 MyISAM 开发,无事务需求,无需改造时可保留。

相关推荐
凌寒114 小时前
Linux(Debian)安装、卸载 MySQL
linux·运维·mysql·debian
oneslide5 小时前
分享一个MySQL数据库备份恢复脚本--II
数据库·mysql
紫麦熊5 小时前
react+ts+vite+tailwind+shadcn
1024程序员节
q***23925 小时前
MySQL数据库误删恢复_mysql 数据 误删
数据库·mysql·adb
合作小小程序员小小店5 小时前
web网页开发,在线%图书管理%系统,基于Idea,html,css,jQuery,java,ssm,mysql。
java·前端·后端·mysql·jdk·intellij-idea
日日行不惧千万里5 小时前
MediaMTX详解
1024程序员节
IUGEI5 小时前
【MySQL】SQL慢查询如何排查?从慢查询排查到最终优化完整流程
java·数据库·后端·mysql·go
合作小小程序员小小店6 小时前
web网页开发,在线%食堂管理%系统,基于Idea,html,css,jQuery,java,ssm,mysql。
java·前端·mysql·html·intellij-idea·jquery
w***4816 小时前
Springboot项目本地连接并操作MySQL数据库
数据库·spring boot·mysql
友友马7 小时前
『MySQL』 - 事务 (二)
数据库·mysql·oracle