13人参与 • 2026-03-17 • Mysql
索引结构提供了高效的数据检索方式,索引信息与数据记录均存储于文件系统中,具体而言是存储在页结构中。索引的实现依赖于存储引擎,mysql 服务器通过存储引擎完成对表数据的读写操作。不同存储引擎的数据存储格式各异,部分存储引擎(如 memory)甚至不使用磁盘存储数据,而是将数据保存在内存中。
通过以下命令可以查看 mysql 支持的所有存储引擎:
show engines;
查询结果示例:
| 存储引擎 | 支持状态 | 说明 | 事务 | 分布式事务 | 保存点 |
|---|---|---|---|---|---|
| innodb | 默认 | 支持事务、行级锁和外键 | 是 | 是 | 是 |
| myisam | 是 | 传统存储引擎,不支持事务 | 否 | 否 | 否 |
| memory | 是 | 基于哈希索引,数据存储于内存,适用于临时表 | 否 | 否 | 否 |
| csv | 是 | 以 csv 格式存储数据 | 否 | 否 | 否 |
| archive | 是 | 高压缩比的归档存储引擎 | 否 | 否 | 否 |
| blackhole | 是 | 黑洞存储引擎,写入的数据不会被保存 | 否 | 否 | 否 |
| federated | 否 | 联邦存储引擎,用于访问远程表 | 空 | 空 | 空 |
| mrg_myisam | 是 | myisam 表的集合 | 否 | 否 | 否 |
| performance_schema | 是 | 性能监控与诊断 | 否 | 否 | 否 |
版本差异
mysql 在不同版本中采用不同的默认存储引擎:
若在创建表时未显式指定存储引擎,mysql 将自动使用默认存储引擎。
查看当前 mysql 版本
select version();
查看默认存储引擎
show variables like 'default_storage_engine';
查询结果示例(mysql 5.6.40):
| variable_name | value |
|---|---|
| default_storage_engine | innodb |
修改默认存储引擎
my.cnfmy.ini[mysqld] 部分:[mysqld] default-storage-engine = innodb
重启 mysql 服务使配置生效:
systemctl restart mysqld.service
方式二:通过 sql 命令修改(会话级别)
set default_storage_engine = myisam;
各存储引擎核心特性
count(*) 查询效率较高核心区别:innodb 与 myisam 的三大关键差异在于事务支持、外键约束和行级锁定。
功能特性对比表
| 功能 | myisam | memory | innodb |
|---|---|---|---|
| 存储限制 | 258 tb | ram | 64 tb |
| 事务支持 | × | × | √ |
| 全文索引支持 | √ | × | √(5.6+) |
| b 树索引支持 | √ | √ | √ |
| 哈希索引支持 | × | √ | √(自适应) |
| 集群索引支持 | × | × | √ |
| 数据索引支持 | × | √ | √ |
| 数据压缩支持 | √ | × | × |
| 空间使用率 | 低 | n/a | 高 |
| 外键支持 | × | × | √ |
innodb 存储引擎
innodb 提供了完善的事务管理、崩溃恢复能力和并发控制机制。其主要优势在于:
主要劣势:
myisam 存储引擎
myisam 适用于以读取和插入操作为主、更新和删除操作较少且对事务要求不高的系统。其主要优势在于:
主要劣势:
选型建议
innodb 是处理大规模数据的首选存储引擎。除非存在特殊的业务需求,否则应优先选择 innodb 存储引擎。
innodb 核心优势
| 操作描述 | sql 语句 |
|---|---|
| 查看表的存储引擎 | show table status like 表名称; |
| 创建表时指定存储引擎 | create table 表名称 (…) engine = 存储引擎名称; |
| 修改表的存储引擎 | alter table 表名称 engine = 存储引擎名称; |
| 查看数据库所有表的存储引擎 | select table_name, engine from information_schema.tables where table_schema = ‘数据库名称’; |
| 查看表的创建语句(包括存储引擎) | show create table 表名称; |
innodb 将数据划分为若干个页(page),默认页大小为 16kb。页是磁盘与内存之间数据交换的基本单位,即每次至少从磁盘读取 16kb 数据到内存,或将内存中的 16kb 数据刷新到磁盘。
设计原理:数据库不以行为单位进行读取,否则每次磁盘 i/o 操作仅能处理一行数据,效率极低。
在数据库系统中,无论读取一行还是多行数据,都会将这些行所在的整个页加载到内存。因此,页是数据库管理存储空间和执行 i/o 操作的最小单位,一个页可以存储多行记录。
不同数据库系统的页大小
查看 innodb 页大小:
show variables like '%innodb_page_size%';
查询结果默认为 16384 字节,即 16kb。
页之间通过双向链表关联,无需在物理结构上连续存储。每个数据页内部的记录按主键值从小到大组成单向链表。为了提高查询效率,每个数据页会为其中的记录生成页目录(page directory),通过主键查找记录时,可以在页目录中使用二分查找法快速定位到对应的槽(slot),然后遍历该槽对应分组中的记录即可快速找到目标记录。
innodb 采用分层的存储结构,从小到大依次为:行(row)、页(page)、区(extent)、段(segment)、表空间(tablespace)。


存储结构层次关系
区(extent)
区是比页更高一级的存储结构。在 innodb 中,一个区包含 64 个连续的页。由于页的默认大小为 16kb,因此一个区的大小为 64 × 16kb = 1024kb = 1mb。
段(segment)
段由一个或多个区组成。区在文件系统中是连续分配的空间(在 innodb 中为连续的 64 个页),但段中的区之间无需相邻。段是数据库的分配单位,不同类型的数据库对象以不同的段形式存在。创建表时会创建表段,创建索引时会创建索引段。
根据存储内容和用途的不同,innodb 中的段主要分为以下三种类型:
1. 数据段(data segment / leaf node segment)
数据段用于存储表的实际数据行,对应 b+ 树索引结构的叶子节点。
2. 索引段(index segment / non-leaf node segment)
索引段用于存储索引的非叶子节点数据,对应 b+ 树索引结构的内部节点。
3. 回滚段(rollback segment / undo segment)
回滚段用于存储事务的回滚信息(undo log),是 innodb 事务机制的核心组件。
三种段的协同工作


段类型对比表
| 特性 | 数据段 | 索引段 | 回滚段 |
|---|---|---|---|
| 存储内容 | 完整的行数据 | 索引键值和指针 | 数据修改前的旧版本 |
| 对应结构 | b+ 树叶子节点 | b+ 树非叶子节点 | undo log |
| 主要用途 | 存储表数据 | 加速数据检索 | 事务回滚和 mvcc |
| 创建时机 | 创建表时 | 创建索引时 | 事务修改数据时 |
| 生命周期 | 与表同生命周期 | 与索引同生命周期 | 事务提交后可清理 |
| 访问频率 | 高(数据查询) | 高(索引查询) | 中(事务回滚、mvcc) |
表空间(tablespace)
表空间是逻辑容器,用于存储段。一个表空间可以包含一个或多个段,但一个段只能属于一个表空间。数据库由一个或多个表空间组成,表空间从管理角度可划分为系统表空间、用户表空间、撤销表空间、临时表空间等。
到此这篇关于mysql 存储引擎innodb 架构与原理深度解析的文章就介绍到这了,更多相关mysql 存储引擎innodb内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论