cmu15545-数据访问方式:B+树(B+Tree)
基本概念
基于磁盘的B+树
为什么使用B+数进行数据访问(Access Method):
- 天然有序,支持范围查找
- 支持遍历所有数据,利用顺序IO
- 时间复杂度为\(O(logn)\),满足性能需求
- 相比于B树,数据访问都在叶子结点:磁盘空间利用率高;并发冲突减少
一个基础的B+树:
- 三类借点:根结点,中间结点,叶子结点
- 数据分布:根结点和中间结点只存储索引,叶子结点存储数据
- 指针关系:父子指针,兄弟指针
基于磁盘的B+树映象:
一个结点存储在一个堆文件(Heap File)页中;页ID(PageId)代替指针的作用。
键值联合存储
键值分别存储
B+树的叶子结点存储实际数据,这个数据如何理解,取决于不同的数据库实现:有些存储RecordID,有些基于索引组织(Index-Organized Storage)的数据库则直接存储元组(Tuple)数据。
如果不了解RecordID,数据组织方式,可以参看这篇博文。
查询与索引
最左前缀匹配
有联合索引<a,b,c>
,支持如下查询条件
(a=1 AND b=2 AND c=3)
(a=1 AND b=2)
如果所有不满足最左前缀匹配原则,需要全表扫描。
如何处理重复键
加上RecordID使其变成唯一键
叶子结点溢出(没有实际系统采用)
聚簇索引
- 一个表只能有一个聚簇索引
- 索引键和值存储在一起
- 数据按照索引的键排序
- 操作数据时要同步操作索引
聚簇索引是非必须的,取决于数据库具体实现,Mysql和SQLite中数据直接用聚簇索引组织。
用B+树实现聚簇索引可以很方便地实现范围查询和便利,充分利用顺序IO。
对于非聚簇索引,虽然索引的键有序,但是对应的数据在磁盘上不一定是顺序存储的,所以很有效的方式是先得到PageID,后根据PageID进行排序,最后获取数据,充分利用顺序IO。
设计选择
结点大小(Node Size)
存储设备读取数据越慢,越需要利用顺序IO,结点就越大;
存储设备读取数据越快,越需要减少冗余数据读取,结点就越小。
- HDD:~1MB
- SSD:~10KB
- In-Memory:~512B
合并阈值(Merge Thredshold)
结点中的键数量低于半满的时候,不会立刻进行合并,而是允许小结点存在,然后再周期性地重建整棵树。
PostgreSQL中称其为不平衡的B+树("non-balanced" B+Tree, nbtree)。
变长键(Variable-length Keys)
- 指针:键存储指向实际数据的指针【无法利用顺序IO,因为要跳转去读取指针内容】
- 变长结点
- 填充数据(Padding)
实际系统中的索引数据和堆文件数据一样,是能存结点就存结点中,是在存不下存指针。
结点内部搜索(Intra-Node Search)
线性查找:由于SIMD指令集存在,实际顺序查询,其实可以是批处理
二分查找
插值法:键没有间隙的时候(自增),可以直接计算出偏移
优化手段
Pointer Swizzling
基本思想:当一个对象从磁盘加载到内存时,将其磁盘地址转换成内存地址(swizzling),以便程序在内存中直接通过指针访问。
例子:比如主键索引的B+树根结点读取到Buffer Pool后,会被pin住,不被置换出去,所以此时可以直接用内存指针访问根结点,省略用PageID问Buffer Pool要内存地址的步骤。
图示:


Bε-trees
一种B+树的写优化。
基本思想:更新时不直接修改数据 ,而是记录日志(类似于log-structured data storage)。
日志记录在结点上,当结点日志记录满以后,该结点的日志下推到孩子结点。
Bulk Insert
基本思想:由底至顶创建B+树,而不是由顶至底。
减少了插入时树的结构变化,前提是需要预先排序数据。
Keys: 3, 7, 9, 13, 6, 1
Sorted Keys: 1, 3, 6, 7, 9, 13
Prefix Compression
基本思想:字典序压缩前缀。
Deduplication
基本思想:非唯一索引中避免重复存储相同键。
Suffix Truncation
基本思想:中间结点只是起引路作用,所以存储能辨识的最小前缀即可。


cmu15545-数据访问方式:B+树(B+Tree)的更多相关文章
- ADO.NET编程之美----数据访问方式(面向连接与面向无连接)
最近,在学习ADO.NET时,其中提到了数据访问方式:面向连接与面向无连接.于是,百度了一下,发现并没有很好的资料,然而,在学校图书馆中发现一本好书(<ASP.NET MVC5 网站开发之美&g ...
- 关系型数据库工作原理-查询优化器之数据访问方式(翻译自Coding-Geek文章)
本文翻译自Coding-Geek文章:< How does a relational database work>.原文链接:http://coding-geek.com/how-data ...
- OPC Utgard的数据访问方式
1.同步读取某个点位的值 Item项的read()方法 Server server = new Server(BaseConfiguration.getCLSIDConnectionInfomatio ...
- (转载)西门子PLC学习笔记十五-(数据块及数据访问方式)
一.数据块 数据块是在S7 CPU的存储器中定义的,用户可以定义多了数据块,但是CPU对数据块数量及数据总量是有限制的. 数据块与临时数据不同,当逻辑块执行结束或数据块关闭,数据块中的数据是会保留住的 ...
- ClownFish:比手写代码还快的通用数据访问层
http://www.cnblogs.com/fish-li/archive/2012/07/17/ClownFish.html 阅读目录 开始 ClownFish是什么? 比手写代码还快的执行速度 ...
- 在WCF数据访问中使用缓存提高Winform字段中文显示速度
在我们开发基于WCF访问方式的Winform程序的时候,一般情况下需要对界面显示的字段进行中文显示的解析.如果是硬编码进行中文显示,那么除了不方便调整及代码臃肿外,性能上没有什么问题,但是不建议这样处 ...
- 三、Spring——数据访问
1.Spring 对 DAO的支持 Spring支持目前大多数常用的数据持久化技术,Spring定义了一套面向DAO层的异常体系,并未各种支持的持久化技术提供了异常转换器.这样,我们在设计DAO接口时 ...
- Android中的5种数据存储方式
本文转自 http://hi.baidu.com/maguowei/blog/item/7aca46c25574a33ae5dd3ba4.htmlAndroid数据存储Android提供了5种方式存 ...
- [翻译]比较ADO.NET中的不同数据访问技术(Performance Comparison:Data Access Techniques)
Performance Comparison: Data Access Techniques Priya DhawanMicrosoft Developer Network January 2002 ...
- XAF-列表视图数据访问模式
本主题介绍有关列表视图如何提供数据访问的几种方式.请注意,选择正确的方式对于实现XAF应用程序的最佳性能至关重要. 数据访问模式概述 在模型编辑器中,通过 视图-> <ListV ...
随机推荐
- windows启动jar包并显示标题
cmd启动java的jar并显示窗口标题 title xx服务 D: cd D:\xx服务 java -jar guns-vip-main.jar 文件名名为 run.bat 双击即可运行
- AntSK:在无网络环境中构建你的本地AI知识库的终极指南
亲爱的读者朋友们,我是许泽宇,今天我将深入探讨一个引人注目的开源工具--AntSK.这个工具让您在没有互联网连接的情况下,仍然能够进行人工智能知识库的对话和查询.想象一下,即使身处无网络环境中,您也可 ...
- ubuntu 安装psycopg2包
psycopg2 库是 python 用来操作 postgreSQL 数据库的第三方库. 执行:pip3 install psycopg2==2.8.4 有可能会报错: Collecting psyc ...
- 关于对 Tomcat 进行小版本升级的快速解决方案
1.背景描述 原来的 Tomcat 在部署时,使用的是最新的版本 9.0.40 . 经过一段时间后,在原来的 Tomcat 版本中,发现存在漏洞. 因此,需要将旧版本(9.0.40)升级到没有漏洞的新 ...
- android 播放视频页面黑屏,且报错:Couldn't open 'xxxxxx' java.io.FileNotFoundException: No content provider:
原因为,activity的顶部布局,VideoView设定了android:background="@color/bg_black"去掉就可以了 之前跑着都正常,改了UI后就没有去 ...
- box-sizing属性的理解
使用原因 盒模型布局中padding与border也是具有尺寸的,为避免其对页面布局产生影响,可使用box-sizing: border-box;属性设置盒模型,此时便可只用设置元素宽高即可. 属性详 ...
- C++: 虚函数,一些可能被忽视的细节
C++: 虚函数,一些可能被忽视的细节 引言:关于C++虚函数,对某些细节的理解不深入,可能导致我们的程序无法按预期结果运行,或是表明我们对其基本原理理解不够透彻.本文详细解答以下几个问题:实现多态, ...
- git 乱操作
https://www.cnblogs.com/qybk/p/10880901.html 错误提示一样,只是我是在我自己的分支(xxx_dev)里.所以以下要改一下. git pull origin ...
- MyBatis——使用Mapper代理开发
使用 Mapper 代理开发方式完成入门案例 1.定义与SQL映射文件同名的Mapper接口,并将 Mapper 接口和SQL映射文件放置在同一目录下 (企业开发中,通常是将配置文件统 ...
- MyBatis——简介
MyBatis MyBatis 是一款优秀的持久层框架,用于简化 JDBC 开发 官网:https://mybatis.net.cn/ 持久层 负责将数据保存到数据库的那一层代码 javaEE 三层架 ...