ddia-读书笔记 第三章 数据存储和检索

数据存储和检索

如何存储数据,如何查找数据

最简单的结构
底层结构:一个纯文本文件,其中每行包含一个key-value对

插入: 每次插入即追加新的内容到文件末尾,相同的值不会覆盖。

查询: 查看文件中最后一次出现的值来找到最新的值。

追加到文件尾部的方式通常足够高效,这种机制叫做日志(log),这里的日志表示的是一个仅能追加的记录序列集合。

问题: 查找会很慢,需要遍历从头到尾,o(n)。为了高效的查找,需要新的结构:索引。

索引

为了高效的查找数据,需要索引。
基本思想都是保留一些额外的元数据,作为路标,帮助定位想要的数据。
任何类型的索引通常都会降低写的速度。

哈希索引

把每个key和对应的位置的偏移量都建立映射(一般内存中)。通过偏移量,只需要最多一次磁盘寻址,就可以将value加载到内存。

优化: 如果一直追加到一个文件中,最终会用尽磁盘。将log分解成一定大小的段,然后在这些段上执行压缩合并,丢弃重复的key,只保留最新的。

log结构的优点: 顺序写。追加的形式,方便控制并发和崩溃恢复。合并段可以整理碎片。

哈希索引的缺点: 占内存。区间查询效率低。

SSTables和LSM-Tree (log结构)

排序字符串表 SSTable,段文件要按key有序,每个键在每个合并的段文件中只能出现一尺(压缩过程已经确保了)。可以只保存部分key索引,然后找到最近的索引,再继续查找。

插入: 写内存中的tree结构,当大于某个阈值时,写入磁盘。

查询: 先找内存,再找磁盘。

问题: 崩溃会丢失内存中的数据。需要在磁盘上保留单独的日志,每个写入都立即追加到该日志。内存写入磁盘时,该日志可丢弃。

基于合并和压缩排序文件原理的存储引擎通常都被成为LSM(Log-Structured Merge-Tree)存储引擎。

优化: 查询一个不存在的数据,可能很慢。使用布隆过滤器。SSTables压缩和合并的具体顺序和时间,大小分级和分层压缩。

优点: 支持区间查询,顺序写入。

B-trees (原地更新)

固定大小的块或页,页是内部读/写的最小单元。这种设计更接近底层的硬件。

  • 插入: 查找到其范围,再添加到改页。可能产生页分裂。
  • 查询: 从tree的根开始查找。
  • 问题: 写操作是使用新数据覆盖磁盘上的旧页。不是顺序写。对于普通磁盘,需要将磁头首先移动到正确的位置,然后旋转扇面,最后用新数据覆盖相应的扇区。对于SSD,由于SSD必须一次擦除并重写非常大的存储新片块,情况会更为复杂
  • 由于操作可能涉及多个不同的页,可能完成部分页写入之后崩溃。为了从崩溃中恢复,需要额外的数据结构:预写日志(write-ahead log,WAL),也成为重做日志
优化:

不使用覆盖页来写入和维护WALl来进行崩溃恢复。使用写时复制
保存键的缩略信息,而不是完整的键,将更多的键压入到页中,让树具有更高的分支因子,从而减少层数。(B+树)
相邻子页按顺序保存
双向链表
分形树?

对比 B-tree 和 LSM-tree

LSM-tree 写入更快(先写内存,然后顺序写入磁盘) B-tree读取更快
LSM-tree 在压缩过程中有时会干扰正在进行的读写操作。(磁盘资源有效)。对平均时间影响较小,但对较高的百分位数,有时会相当高。而B-tree的响应延迟更具确定性。未合并段越来越多,最后可能造成雪崩。
B-tree 的每个键恰好唯一对应索引中的某个位置,可以直接通过建上的锁来实现事务。 log结构可能在不同段有多个副本。

在索引中存储值

索引中的键是查询搜索的对象,而值可以使实际行,也可以是引用(存储的具体位置叫堆文件)
避免索引到堆文件的跳转,将行直接存储在索引中,称为聚集索引。
只存储索引中的数据的引用叫做非聚集索引。

OLTP 和 OLAP

列式存储

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值