forked from mrchuanxu/RegularNotes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bplus_tree.cpp
105 lines (97 loc) · 3.43 KB
/
bplus_tree.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/***
* B+树的前世今生
* MySql数据库索引是如何实现的
* 为了加速数据库中数据的查找速度,常用的处理思路是对表加索引
* 数据库索引是如何实现的?
* 底层使用的是什么数据结构和算法?
*
* 1. 解决问题的前提是定义清楚问题,对一些模糊的需求进行假设来限定要解决的问题范围
* > 执行效率和存储空间
* 执行效率高,存储空间低
* 尝试几个数据结构来解决这个问题
* 1. 散列表,O(1)查找,但是不支持区间快速查找数据
* 2. 平衡二叉查找树 O(logn) 但是也不支持区间快速查找数据
* 3. 跳表,支持区间查找 O(logn)
*
* 跳表可以吗?可以解决问题,但是还有一种结构叫B+🌲
* 通过二叉查找树演化而来
* 怎么演化?
* 1. 让二叉查找树支持按照区间来查找数据
* 改造: 树中的节点并不存储数据本身,而是存储索引
* 除此之外,我们把每个叶子节点串在一条链表上
* 链表中的数据是从小到大有序的
* 例如 6,10,15,23,27,33,42
* 链表在最底下
*
* 若占用过多内存,可以考虑💭一下磁盘
* 通过🌲的高度即IO操作次数(尽量减少操作IO)
* 那么如何降低树的高度(height)
*
* 通过构建m叉树
* 5叉树,16个数据,高度为2
* 4叉树,16个数据,高度为3
* 当m=100,1亿个数据,高度也只为3
*
* 高度为3也只需要IO 3次
*
* 因而查询的效率也高了
*
* ***/
#include <iostream>
#include <vector>
using namespace std;
/***
* B+ 树非叶子节点的定义
* 假设keywords = [3,5,8,10]
* 4个键值将数据分为5个区间:(通过将区间存在节点中)
* (-INF,3),[3,5),[5,8),[8,10),[10,INF)
* 5个区间分别对应: children[0]...children[4]
*
* m值事先计算得到,计算的依据是让所有信息的大小正好等于页的大小
* PAGE_SIZE = (m-1)*4[keywordss大小]+m*8[children大小]
*
* ***/
struct bPlusTreeNode{
static const int m = 5;
int keywords[m-1];
bPlusTreeNode *children[m];
};
/***
* 这是B+树
* B+树中的叶子节点跟内部节点不一样
* 叶子节点存储的是值,而非区间
* 每个叶子节点存储3个数据行的键值以及地址信息
*
* k值是事先计算得到的,计算的依据是让所有信息的大小正好等于页的大小
* PAGE_SIZE = k*4[keywords..大小]+k*8[dataAd..大小]+8[prev大小]+8[next大小]
*
* ***/
struct bPlusTreeLeafNode{
static const int k = 3;
int keywords[k];
long dataAddress[k];
bPlusTreeLeafNode *prev;
bPlusTreeLeafNode *next;
};
/***
* 尽量让每个节点大小等于一个页的大小,读取一个节点只需要一次磁盘IO操作
* ***/
/***
* B+树的增删查改
* 增,写入,分裂节点
* 设置阈值
* 删,删除小于m/2就合并节点
*
* 其实跳表稍加改造也可以替换B+树
* 作为数据库索引实现
*
* B+树的特点
* * 每个绩点中的字节点的个数不能超过m,也不能小于m/2
* * 根节点的子节点个数可以不超过m/2,这是一个例外
* * m叉树只存储索引,并不真正存储数据,这个有点类似跳表
* * 通过链表将叶子节点串联在一起,方便按区间查找
* * 一般情况下,根节点会被存储在内存中,其他节点存储在磁盘中
* B-Tree 就是B树,翻译...
*
* B是低级版的B+,B存数据,B树的字节点不少于m/2的m叉树
* * ***/