MySQL为什么使用B+树来作索引

时间:2024-12-13 22:34:07
<svg viewBox="0 0 800 400" xmlns="http://www.w3.org/2000/svg"> <!-- 根节点 --> <rect x="350" y="20" width="100" height="40" fill="#FFB6C1" rx="5"/> <text x="400" y="45" text-anchor="middle" fill="black">50</text> <!-- 第二层节点 --> <rect x="200" y="120" width="140" height="40" fill="#ADD8E6" rx="5"/> <text x="270" y="145" text-anchor="middle" fill="black">20 | 35</text> <rect x="460" y="120" width="140" height="40" fill="#ADD8E6" rx="5"/> <text x="530" y="145" text-anchor="middle" fill="black">70 | 85</text> <!-- 连接线 --> <line x1="400" y1="60" x2="270" y2="120" stroke="black" stroke-width="2"/> <line x1="400" y1="60" x2="530" y2="120" stroke="black" stroke-width="2"/> <!-- 叶子节点 --> <rect x="50" y="220" width="120" height="40" fill="#98FB98" rx="5"/> <text x="110" y="245" text-anchor="middle" fill="black">10 | 15</text> <rect x="190" y="220" width="120" height="40" fill="#98FB98" rx="5"/> <text x="250" y="245" text-anchor="middle" fill="black">20 | 30</text> <rect x="330" y="220" width="120" height="40" fill="#98FB98" rx="5"/> <text x="390" y="245" text-anchor="middle" fill="black">35 | 45</text> <rect x="470" y="220" width="120" height="40" fill="#98FB98" rx="5"/> <text x="530" y="245" text-anchor="middle" fill="black">70 | 75</text> <rect x="610" y="220" width="120" height="40" fill="#98FB98" rx="5"/> <text x="670" y="245" text-anchor="middle" fill="black">85 | 90</text> <!-- 连接线到叶子节点 --> <line x1="270" y1="160" x2="110" y2="220" stroke="black" stroke-width="2"/> <line x1="270" y1="160" x2="250" y2="220" stroke="black" stroke-width="2"/> <line x1="270" y1="160" x2="390" y2="220" stroke="black" stroke-width="2"/> <line x1="530" y1="160" x2="530" y2="220" stroke="black" stroke-width="2"/> <line x1="530" y1="160" x2="670" y2="220" stroke="black" stroke-width="2"/> <!-- 叶子节点之间的链表连接 --> <path d="M170 240 L190 240" stroke="blue" stroke-width="2" marker-end="url(#arrow)"/> <path d="M310 240 L330 240" stroke="blue" stroke-width="2" marker-end="url(#arrow)"/> <path d="M450 240 L470 240" stroke="blue" stroke-width="2" marker-end="url(#arrow)"/> <path d="M590 240 L610 240" stroke="blue" stroke-width="2" marker-end="url(#arrow)"/> <!-- 箭头定义 --> <defs> <marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto" markerUnits="strokeWidth"> <path d="M0,0 L0,6 L9,3 z" fill="blue"/> </marker> </defs> <!-- 图例 --> <rect x="50" y="320" width="20" height="20" fill="#FFB6C1"/> <text x="80" y="335" fill="black">根节点</text> <rect x="150" y="320" width="20" height="20" fill="#ADD8E6"/> <text x="180" y="335" fill="black">索引节点</text> <rect x="250" y="320" width="20" height="20" fill="#98FB98"/> <text x="280" y="335" fill="black">叶子节点(数据节点)</text> <line x1="350" y1="330" x2="400" y2="330" stroke="blue" stroke-width="2" marker-end="url(#arrow)"/> <text x="430" y="335" fill="black">叶子节点链表</text> </svg> 让我解释这个B+树的关键特征: 1. 层级结构: - 顶层粉色节点是根节点 - 中间蓝色节点是索引节点 - 底层绿色节点是叶子节点,存储实际数据 2. 节点特点: - 每个非叶子节点可以包含多个键值 - 键值用于指引查找方向 - 叶子节点存储实际数据记录 3. 特殊设计: - 所有叶子节点通过蓝色箭头连接,形成有序链表 - 这种设计特别有利于范围查询 - 非叶子节点只存储索引信息,不存储实际数据 4. 数据查找示例: - 要查找值为75的记录: 1. 从根节点50开始 2. 75>50,所以往右走到70|85 3. 70<75<85,定位到对应叶子节点70|75 5. 范围查询示例: - 要查找20到45之间的所有记录: 1. 先找到20所在的叶子节点 2. 通过蓝色箭头顺序遍历到45 3. 期间经过的所有节点就是要查询的范围 这种结构设计使得B+树特别适合数据库索引: - 层级结构减少磁盘I/O次数 - 叶子节点链表支持高效的范围查询 - 所有数据都在叶子节点,查询路径稳定