
1. 从二叉搜索树到数据库索引的演化第一次接触二叉搜索树(BST)是在大学数据结构课上当时觉得这种能自动排序的数据结构真神奇。但当我尝试用BST实现字典程序时发现当输入数据有序时树会退化成链表查询速度从O(log n)暴跌到O(n)。这个痛点正是数据库索引需要解决的核心问题。二叉搜索树的本质是通过二分思想提升查询效率。想象图书馆的书架如果书籍完全乱序找书需要O(n)时间如果按编号排列就能二分查找。BST的每个节点都是个决策点根据比较结果决定向左或向右搜索。但在动态插入场景下简单的BST会面临严重的平衡问题。2. 平衡的艺术AVL与红黑树为了解决平衡问题两位苏联数学家发明了AVL树。我曾用AVL树实现过实时股票行情系统它的平衡策略非常严格——要求任意节点左右子树高度差不超过1。维护这种平衡需要四种旋转操作// AVL树的右旋示例 Node* rightRotate(Node* y) { Node* x y-left; Node* T2 x-right; x-right y; y-left T2; // 更新高度 y-height max(height(y-left), height(y-right)) 1; x-height max(height(x-left), height(x-right)) 1; return x; }但在高频写入场景下AVL的严格平衡反而成了负担。这时红黑树展现出优势它通过颜色标记和五大规则实现近似平衡。在实现Java的TreeMap时我发现红黑树的插入性能比AVL高约20%虽然查询稍慢但综合性能更好。其核心规则包括节点非红即黑根节点必须黑红色节点不能相邻从任意节点到叶子的黑节点数相同3. 磁盘友好的B树家族当数据量大到内存无法容纳时B树登场了。第一次在MySQL中见到B树索引时我惊讶于它的设计之精妙。与二叉树不同B树的每个节点可以包含多个键和子节点指针典型结构如下------------------- | 键1 | 键2 | ... | 键n | ------------------- | 指针0 | 指针1 | ... | 指针n | -------------------这种胖节点设计大幅减少了磁盘I/O次数。假设节点大小设置为4KB每个键值占8字节指针占6字节那么单个节点可存储约200个键。这意味着仅需3次磁盘读取200^3800万就能访问百万级数据。4. B树数据库索引的终极选择在LevelDB存储引擎开发中我深刻体会到B树相比B树的优势。B树的所有数据都存储在叶子节点形成有序链表非叶子节点仅作索引。这种设计带来三大优势更少的I/O次数同样深度下能索引更多数据稳定的查询效率任何查询都要走到叶子节点高效的范围查询叶子节点链表直接遍历以下是B树与B树的直观对比特性B树B树数据存储位置所有节点仅叶子节点查询稳定性不稳定稳定O(log n)范围查询需要中序遍历链表直接扫描空间利用率较低更高5. 实战中的索引优化在电商系统开发中我们遇到过索引失效的典型案例。某商品表有联合索引(category, price)但查询WHERE price 100时索引失效这就是最左前缀原则在起作用。正确的索引设计需要考虑区分度高的列在前避免过度索引注意索引列的数据类型定期进行索引重建对于时间序列数据我们发现使用LSM-Tree基于B树改进比纯B树写入性能提升5-10倍这正是LevelDB和RocksDB的选择。6. 树结构的本质思考经过多年实践我理解到各种树结构的本质都是在三个维度寻找平衡查询效率减少比较和I/O次数维护成本插入/删除时的调整开销存储效率空间利用率与缓存友好性AVL胜在查询但维护成本高红黑树取折中B树为磁盘优化。正如Knuth所说树结构的艺术在于在动态变化中保持平衡。