InnoDB 与 MyISAM 核心区别

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
喜欢就支持一下吧
点赞10 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容