1. 数据库存储引擎的进化之路
作为一名数据库内核开发者,我经常被问到:"为什么我们需要这么多不同类型的数据库?"答案很简单:因为不同的业务场景对数据存储和访问的需求截然不同。就像你不能用一把螺丝刀去完成所有维修工作一样,数据库也需要针对不同场景进行专门优化。
1.1 从文本文件到专业存储引擎
让我们从一个最简单的例子开始:假设我们要用纯文本文件存储用户数据。最直观的做法就是把每条记录追加到文件末尾:
plaintext复制1,张三,25,北京
2,李四,30,上海
3,王五,28,广州
这种追加写入(append-only)的方式在写入性能上非常出色,因为磁盘的顺序写入速度可以达到随机写入的数十倍。但问题来了:当我们需要查找ID为100万的用户时,必须从头开始扫描整个文件,时间复杂度是O(N),这在数据量大的情况下是完全不可接受的。
提示:现代SSD的顺序写入速度约为500MB/s,而随机写入可能只有50MB/s。这就是为什么所有高性能存储系统都尽量避免随机写入。
1.2 索引的革命:从哈希表到B+树
为了解决查找效率问题,我们需要引入索引。就像书籍的目录一样,索引可以帮助我们快速定位数据。最常见的两种索引结构是哈希表和B+树。
哈希索引通过哈希函数将键映射到内存地址,查找时间复杂度是O(1)。下面是一个简单的哈希索引实现示例:
python复制class HashIndex:
def __init__(self):
self.index = {}
def put(self, key, offset):
self.index[key] = offset
def get(self, key):
return self.index.get(key)
虽然哈希索引查找极快,但它有两个致命缺陷:
- 无法支持范围查询(如查找年龄在20-30岁的用户)
- 哈希表必须全部放在内存中,数据量大时不现实
这就是为什么B+树成为了关系型数据库的标准索引结构。B+树有以下几个关键特点:
- 多路平衡查找树,每个节点可以包含数百个子节点
- 所有数据都存储在叶子节点,内部节点只存键和指针
- 叶子节点
