存储与检索(上)
驱动数据库的数据结构
- 日志
- 这个词通常指应⽤⽇志:即应⽤程序输出的描述发⽣事情的⽂本。本书在更普遍的意义下使⽤⽇志这⼀词:⼀个仅追加的记录序列。它可能压根就不是给⼈类看的,使⽤⼆进制格式,并仅能由其他程序读取。
- 索引
- 加快查询速度,但是会减慢写入速度
哈希索引
- 文件格式 - 二进制
- 删除记录
- 崩溃恢复
- 部分写入记录
- 并发控制
SSTables 和 LSM 树
构建和维护 SSTables
⽤SSTables制作LSM树
性能优化
B树
让 B 树更可靠
为了使数据库对崩溃具有韧性,B树实现通常会带有⼀个额外的磁盘数据结构:预写式⽇志(WAL,write-ahead-log)(也称为重做⽇志(redo log))。这是⼀个仅追加的⽂件,每个B树修改都可以应⽤到树本身的⻚⾯上。当数据库在崩溃后恢复时,这个⽇志被⽤来使B树恢复到⼀致的状态
B 树优化
- 一些数据库(如LMDB)使⽤写时复制⽅案【21】,⽽不是覆盖⻚⾯并维护WAL进⾏崩溃恢复。修改的⻚⾯被写⼊到不同的位置,并且树中的⽗⻚⾯的新版本被创建,指向新的位置。这种⽅法对于并发控制也很有⽤,我们将在“快照隔离和可重复读”中看到。
- 我们可以通过不存储整个键来节省⻚⾯空间,但可以缩⼩它的⼤⼩。特别是在树内部的⻚⾯上,键只需要提供⾜够的信息来充当键范围之间的边界。在⻚⾯中包含更多的键允许树具有更⾼的分⽀因⼦,因此更少的层次
- 通常,⻚⾯可以放置在磁盘上的任何位置;没有什么要求附近的键范围⻚⾯附近的磁盘上。如果查询需要按照排序顺序扫描⼤部分关键字范围,那么每个⻚⾯的布局可能会⾮常不⽅便,因为每个读取的⻚⾯都可能需要磁盘查找。因此,许多B树实现尝试布局树,使得叶⼦⻚⾯按顺序出现在磁盘上。但是,随着树的增⻓,维持这个顺序是很困难的。相⽐之下,由于LSM树在合并过程中⼀次⼜⼀次地重写存储的⼤部分,所以它们更容易使顺序键在磁盘上彼此靠近。
- 额外的指针已添加到树中。例如,每个叶⼦⻚⾯可以在左边和右边具有对其兄弟⻚⾯的引⽤,这允许不跳回⽗⻚⾯就能顺序扫描。
- B树的变体如分形树【22】借⽤⼀些⽇志结构的思想来减少磁盘寻道(⽽且它们与分形⽆关)。
比较 B 树和 LSM 树
LSM 树的优点
- 支持更高的写入吞吐量
- 可以压缩的更好
LSM 树的缺点
- 如果写⼊吞吐量很⾼,并且压缩没有仔细配置,压缩跟不上写⼊速率。在这种情况下,磁盘上未合并段的数量不断增加,直到磁盘空间⽤完,读取速度也会减慢,因为它们需要检查更多段⽂件。
其他索引结构
- 将值存储在索引中
- 多列索引
- 全文搜索和模糊
- 在内存中存储一切
关键词
- 日志结构
- 面向页面
- 仅追加
- ⽇志(log)
- 索引
- 排序字符串表
- 预写式日志