MySQL InnoDB 存储引擎:B+树叶子节点能存多少数据?
前言
很多人知道 MySQL 使用 B+ 树作为索引结构,但对于一个叶子节点到底能存多少行数据这个问题,往往只知道一个模糊的概念。本文将详细解析这个问题,并通过实际计算帮助你理解。
一、叶子节点存什么?
1.1 叶子节点 vs 非叶子节点
在 InnoDB 的 B+ 树中,节点分为两类:
非叶子节点(包括根节点):
- 只存储索引值 + 指针
- 不存储完整数据
- 作用:导航,快速定位到叶子节点
叶子节点:
- 存储完整的数据行
- 包含所有字段的值
- 所有叶子节点通过双向链表连接
1.2 叶子节点的结构
叶子节点(16KB 的页) ┌──────────────────────────────────────────────┐ │ 第 1 行:id=1 | name=张三 | age=25 | email=... │ │ 第 2 行:id=2 | name=李四 | age=30 | email=... │ │ 第 3 行:id=3 | name=王五 | age=28 | email=... │ │ ... │ │ 第 N 行:能存多少行,取决于每行大小 │ └──────────────────────────────────────────────┘
关键点:
- 页大小固定:16KB(InnoDB 默认)
- 每行大小:根据表结构动态变化
二、计算公式
2.1 核心公式
每个叶子节点能存的行数 = 页大小 ÷ 每行数据大小 = 16384 字节 ÷ 每行大小
2.2 每行大小的构成
一行数据的大小包括:
- 字段数据:所有列的实际数据
- InnoDB 行格式开销:
- 变长字段长度列表(1-2 字节)
- NULL 标志位(1 字节)
- 记录头信息(5 字节)
- 隐藏列:
DB_TRX_ID(事务 ID,6 字节)DB_ROLL_PTR(回滚指针,7 字节)
总开销约:20-30 字节
三、实际计算示例
示例 1:普通用户表(每行 200 字节)
表结构:
CREATE TABLE users (
id BIGINT, -- 8 字节
name VARCHAR(50),-- 假设平均 20 字节
age ,
email (),
created_at DATETIME,
status TINYINT,
(id)
);

