MySQL存储引擎详解

MySQL 存储引擎详解

存储引擎是 MySQL 的核心组件,不同引擎决定了数据的存储方式、索引结构、锁机制等关键特性。

一、什么是存储引擎?

MySQL 采用插件式存储引擎架构,将查询处理与数据存储分离。存储引擎负责数据的存储和提取,不同引擎有不同的特性。

版本演进:

  • MySQL 5.5 之前:默认 MyISAM
  • MySQL 5.5 之后:默认 InnoDB(推荐使用)

二、主流存储引擎对比

特性InnoDBMyISAMMemory
事务支持✅ ACID 事务
锁粒度行级锁表级锁表级锁
外键✅ 支持
MVCC✅ 支持
索引类型B+Tree、全文索引B+Tree、全文索引Hash、B+Tree
崩溃恢复✅ redo log 恢复❌(数据丢失)
存储限制64TB256TB取决于内存
适用场景OLTP、高并发只读/读多写少临时表、缓存

2.1 InnoDB 核心特性

为什么 InnoDB 是默认引擎?

  1. 事务安全:支持 ACID,提供 Commit、Rollback、崩溃恢复
  2. 行级锁:并发性能高,适合高并发写入
  3. MVCC:多版本并发控制,读写不阻塞
  4. 聚簇索引:数据和主键索引存储在一起,主键查询极快
  5. 外键约束:保证数据完整性
  6. 缓冲池:Buffer Pool 缓存热点数据,减少磁盘 IO

InnoDB 存储结构:

1
2
3
4
5
表空间(Tablespace)
└── 段(Segment)
└── 区(Extent,1MB = 64 页)
└── 页(Page,16KB)
└── 行(Row)

2.2 MyISAM 特点

  • 表级锁:并发写入性能差
  • 无事务:不支持回滚
  • 存储分离.frm(表结构)+ .MYD(数据)+ .MYI(索引)
  • 全文索引:早期唯一支持全文索引的引擎(InnoDB 5.6+ 也支持)

适用场景:只读或读多写少的统计分析场景。

2.3 Memory 引擎

  • 数据存内存:极快但重启丢失
  • Hash 索引:等值查询 O(1),但不支持范围查询
  • 表级锁:并发性能有限

适用场景:临时表、会话缓存。

三、InnoDB vs MyISAM 深度对比

3.1 锁机制

1
2
3
4
5
-- MyISAM:表级锁
UPDATE users SET name = 'test' WHERE id = 1; -- 锁整张表

-- InnoDB:行级锁(通过索引加锁)
UPDATE users SET name = 'test' WHERE id = 1; -- 只锁 id=1 的行

注意:InnoDB 只有通过索引条件检索数据才使用行级锁,否则退化为表锁。

3.2 索引结构

引擎主键索引二级索引
InnoDB聚簇索引(叶子存完整行数据)非聚簇索引(叶子存主键值,需回表)
MyISAM非聚簇索引(叶子存数据地址)非聚簇索引(叶子存数据地址)

3.3 count(*) 性能

1
SELECT COUNT(*) FROM users;
  • MyISAM:O(1),表头直接存储行数
  • InnoDB:全表扫描统计(因 MVCC 不同事务看到的行数不同)

四、存储引擎操作

4.1 查看存储引擎

查看 MySQL 版本信息

1
SHOW VARIABLES LIKE '%storage_engine%';

image-20241224160729533

查看 MySQL支持的存储引擎(MySQL8.0.34)

1
SHOW ENGINES;

image-20241224160749270

修改当前数据库的存储引擎

将名为 users表的存储引擎从 MyISAM 切换为InnoDB

1
ALTER TABLE users ENGINE = InnoDB;

在建表时直接指定存储引擎:

1
2
3
4
5
6
CREATE TABLE products (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255),
price DECIMAL(10, 2),
PRIMARY KEY (id)
) ENGINE = MyISAM;

设置默认的存储引擎

在配置文件中设置:

1
2
[mysqld]
default-storage-engine = engine_name

使用SET命令设置:

1
SET default_storage_engine = engine_name;

在当前会话中将默认存储引擎设置为 MyISAM:

1
SET default_storage_engine = MyISAM;