cmu15545-数据访问方式:B+树(B+Tree)

news/2024/11/14 14:31:56/文章来源:https://www.cnblogs.com/timothy020/p/18543773

目录
  • 基本概念
    • 基于磁盘的B+树
    • 查询与索引
  • 设计选择
    • 结点大小(Node Size)
    • 合并阈值(Merge Thredshold)
    • 变长键(Variable-length Keys)
    • 结点内部搜索(Intra-Node Search)
  • 优化手段
    • Pointer Swizzling
    • Bε-trees
    • Bulk Insert
    • Prefix Compression
    • Deduplication
    • Suffix Truncation

基本概念

基于磁盘的B+树

为什么使用B+数进行数据访问(Access Method):

image-20241109143725399

  • 天然有序,支持范围查找
  • 支持遍历所有数据,利用顺序IO
  • 时间复杂度为\(O(logn)\),满足性能需求
  • 相比于B树,数据访问都在叶子结点:磁盘空间利用率高;并发冲突减少

一个基础的B+树:

  • 三类借点:根结点,中间结点,叶子结点
  • 数据分布:根结点和中间结点只存储索引,叶子结点存储数据
  • 指针关系:父子指针,兄弟指针

image-20241113104944036

基于磁盘的B+树映象:

一个结点存储在一个堆文件(Heap File)页中;页ID(PageId)代替指针的作用。

  • 键值联合存储

    image-20241113105746186

  • 键值分别存储

    image-20241113105801713

B+树的叶子结点存储实际数据,这个数据如何理解,取决于不同的数据库实现:有些存储RecordID,有些基于索引组织(Index-Organized Storage)的数据库则直接存储元组(Tuple)数据。

image-20241113110032259

如果不了解RecordID,数据组织方式,可以参看这篇博文。

查询与索引

最左前缀匹配

有联合索引<a,b,c>,支持如下查询条件

  • (a=1 AND b=2 AND c=3)
  • (a=1 AND b=2)

image-20241113111703944

如果所有不满足最左前缀匹配原则,需要全表扫描。

如何处理重复键

  • 加上RecordID使其变成唯一键

    image-20241113111945385

  • 叶子结点溢出(没有实际系统采用)

    image-20241113111956652

聚簇索引

  • 一个表只能有一个聚簇索引
  • 索引键和值存储在一起
  • 数据按照索引的键排序
  • 操作数据时要同步操作索引

聚簇索引是非必须的,取决于数据库具体实现,Mysql和SQLite中数据直接用聚簇索引组织。

用B+树实现聚簇索引可以很方便地实现范围查询和便利,充分利用顺序IO。

image-20241113112518741

对于非聚簇索引,虽然索引的键有序,但是对应的数据在磁盘上不一定是顺序存储的,所以很有效的方式是先得到PageID,后根据PageID进行排序,最后获取数据,充分利用顺序IO。
image-20241113112630957

设计选择

结点大小(Node Size)

存储设备读取数据越慢,越需要利用顺序IO,结点就越大;

存储设备读取数据越快,越需要减少冗余数据读取,结点就越小。

  • HDD:~1MB
  • SSD:~10KB
  • In-Memory:~512B

合并阈值(Merge Thredshold)

结点中的键数量低于半满的时候,不会立刻进行合并,而是允许小结点存在,然后再周期性地重建整棵树。

PostgreSQL中称其为不平衡的B+树("non-balanced" B+Tree, nbtree)。

变长键(Variable-length Keys)

  • 指针:键存储指向实际数据的指针【无法利用顺序IO,因为要跳转去读取指针内容】
  • 变长结点
  • 填充数据(Padding)

实际系统中的索引数据和堆文件数据一样,是能存结点就存结点中,是在存不下存指针。

  • 线性查找:由于SIMD指令集存在,实际顺序查询,其实可以是批处理

    image
  • 二分查找

  • 插值法:键没有间隙的时候(自增),可以直接计算出偏移

    image

优化手段

Pointer Swizzling

基本思想:当一个对象从磁盘加载到内存时,将其磁盘地址转换成内存地址(swizzling),以便程序在内存中直接通过指针访问。

例子:比如主键索引的B+树根结点读取到Buffer Pool后,会被pin住,不被置换出去,所以此时可以直接用内存指针访问根结点,省略用PageID问Buffer Pool要内存地址的步骤。

图示:

imageimage

Bε-trees

一种B+树的写优化。

基本思想:更新时不直接修改数据 ,而是记录日志(类似于log-structured data storage)。

日志记录在结点上,当结点日志记录满以后,该结点的日志下推到孩子结点。

image-20241113133509231

image-20241113133530151

Bulk Insert

基本思想:由底至顶创建B+树,而不是由顶至底。

减少了插入时树的结构变化,前提是需要预先排序数据。

Keys: 3, 7, 9, 13, 6, 1
Sorted Keys: 1, 3, 6, 7, 9, 13

image-20241113133953890

image-20241113134001752

Prefix Compression

基本思想:字典序压缩前缀。

Deduplication

基本思想:非唯一索引中避免重复存储相同键。

Suffix Truncation

基本思想:中间结点只是起引路作用,所以存储能辨识的最小前缀即可。

imageimage

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/832943.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

正向代理理解

正向代理(由客户端代理)

冲刺Day1

Day1 当天站立式会议照片姓名 学号 昨天已完成的工作 今天计划完成的工作 工作中遇到的困难林涛(组长) 3122004618 null 开发登录管理员api 如何进行password保密杨森 3122004629 null 后台文件上传开发 如何进行前后端文件上传协调钟礼骏 3122006504 null 查询家长感兴趣模块…

关于电线平方数(截面积)与功率之间关系的对比表格。该表格主要基于电流承载能力(导线的截面积)与相应的功率传输能力。

关于电线平方数(截面积)与功率之间关系的对比表格。该表格主要基于电流承载能力(导线的截面积)与相应的功率传输能力。电线截面积 (mm) 额定电流 (A) 适用功率 (W) (220V 电压) 适用功率 (W) (380V 电压)0.5 mm 5 A 1100 W 1900 W0.75 mm 8 A 1760 W 3040 W1.0 mm 10 A 220…

在线性坐标系中绘制对数函数图象

本文记述了用 Matplotlib 在线性坐标系中绘制对数函数图象的例子。 代码主体内容如下: ...def main():fig, ax = plt.subplots(figsize=(8,8)) #1ax = configure_axes(ax, Logarithmic Function, 8, 3, 1, 0.25, 1, 0.25) #2x = np.linspace(0.125, 8, 100) …

【JetBrains Rider 2024软件下载与安装教程】

1、安装包Rider2024: 链接:https://pan.quark.cn/s/f3b3360dccc0 提取码:Z8gA Rider-2023.3.2: 链接:https://pan.quark.cn/s/82b63a1e0df3 提取码:XdA8 2、安装教程(建议关闭杀毒软件) 1) 双击下载安装包exe文件安装,弹窗安装对话框2) 点击下一步3) …

推荐一个.NetCore开源的CMS项目,功能强大、扩展性强、支持插件的系统!

推荐一个基于.Net Core开发的开源CMS项目,该项目功能完善、涉及知识点比较多,不管是作为二次开发、还是学习都是不错的选择。01 项目简介 Cofoundry是基于.Net开发的、代码优先开发、具备可扩展且灵活的架构、简单易用的内容管理系统。02 项目框架 1、基于.Net 8开发。 2、数…

如何把markdown文件导出为pdf

1. 下载Prince [下载小工具] 下载后直接安装即可。 2. 添加环境变量先找到小工具的可执行文件Prince.exe的路径。.\Prince\engine\bin把Prince.exe的路径的添加到环境变量中,然后重启vscode。3. 在vs code中把md文件转换成pdfa. 先保证自己有Markdown Preview Enhanced插件, …

xv6 pingpong lab中 父进程parent应该先写后读,顺序不能变(注意是队列,不是栈)

按照图中顺序来写,pipe是队列,先进先出。读取肯定读最前面的,top。写入肯定写最后面back。注意与堆栈stack进行区分

AvaloniaVS2022

AvaloniaVS.VS2022安装和使用 首先下载VS2022专业版 https://visualstudio.microsoft.com/zh-hans/downloads/安装Avalonia for Visual Studio 2022扩展包这里直接安装经常失败,我下载AvaloniaVS.VS2022.vsix 单独安装,直接以管理员安装就可以,时间有点长,耐心等待打开VS20…

Java初识(一)

运行机制:语言处理程序主要分为汇编程序,编译程序,解释程序 效率(编译>解释) 灵活性(编译<解释) 可移植性(编译<解释) 在解释方式下,翻译源程序时不生成独立的目标程序,而编译器则将源程序翻译成独立保存的目标程序 Java解释型面向对象编程语言 基于Java开…