Sqlite pager和B-tree的运行机制
Posted 单片机菜鸟哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sqlite pager和B-tree的运行机制相关的知识,希望对你有一定的参考价值。
Sqlite pager和B-tree的运行机制
官方文档:https://www.sqlite.org/index.html
1、Sqlite 嵌入式设备下的数据库
官方文档:
百度百科:
SQLite,是一款轻型的数据库,是遵守ACID的
关系型数据库
管理系统,它包含在一个相对小的C库
中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式
的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K
的内存就够了。
嵌入式设备本身内存空间小,这一点与sqlite不谋而合。
2、B-Tree和B+Tree
一般我们说B树,就是B-Tree(别说B减树)。
而B+Tree倒是叫做B加树。
2.1 B树
2.1.1 特点
- B树
每个节点都存储数据
,所有节点组成这棵树,并且叶子节点指针为null; - B树中叶节点包含的关键字和其他节点包含的关键字是
不重复
的。
2.1.2 优点
- B树的每一个节点都包含key和value,因此经常访问的元素可能离根节点更近,因此
访问也更迅速
。(可能访问一下就能得到我要的节点数据)
2.2 B+树
2.2.1 特点
- B+树
只有叶子节点存储数据
(B+数中有两个头指针:一个指向根节点,另一个指向关键字最小的叶节点),叶子节点包含了这棵树的所有数据,所有的叶子结点使用链表
相连,便于区间查找和遍历
,所有非叶节点起到索引作用
。 - B+树的索引项只包含对应子树的最大关键字和指向该子树的指针,
不含有该关键字对应记录的存储地址
。 - B+树中查找,无论查找是否成功,每次都是一条从根节点到叶节点的路径。
2.2.2 优点
-
所有的叶子结点使用链表相连,便于
区间查找和遍历
。B树则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。 -
b+树的中间节点不保存数据,能
容纳更多节点元素
。
2.3 B树和B+树的共同特点
考虑磁盘IO的影响,它相对于内存来说是很慢的。数据库索引是存储在磁盘上的,当数据量大时,就不能把整个索引全部加载到内存了,只能逐一加载每一个磁盘页(对应索引树的节点)
。所以我们要减少IO次数,对于树来说,IO次数就是树的高度,而“矮胖”就是b树的特征之一,m的大小取决于磁盘页的大小。
3、Sqlite结构
在看一些网络帖子的时候,很多文章说 Sqlite中组织管理数据库文件存储的机制为B-树。(这句话不够严谨)。
严格意义上来说:
在Sqlite中使用了B-树和B+树。数据记录存储使用B-树,表索引使用B+树。这里可以叫做文件存储机制和索引机制。
不管是索引还是数据记录存储,最终都会涉及到持久化数据存储,也就是存储在磁盘中。
3.1 数据库文件格式 —— Pager
Sqlite中有一个概念叫做页面(Pager)。一个数据库文件被连续分割为n个页面,并给了一个页面号。
一个数据库由多个B树(统称B-、B+)组成 —— 每张表以及每个索引各对应一个B树(
表使用B+树,索引使用B-树
,这里需要涉及到B树优点)。
数据库中每张表或者索引都以根页面作为第一页。所有索引和表的根页面都存储在sqlite_master 中。
包括:
Root Page
:根页面Internal Pag
e:内部页面Leaf Page
:叶子页面
3.2 B-Tree 记录
- B-Tree中的页由一系列B-tree记录组成,这些记录叫做有效负载。一个B-tree记录仅仅由两个域组成:键值域(Key)和数据域(Data)。键值域是每个数据库表中所包含的RowId值或者主键值。用来保持记录有序并且方便记录查询;
- 在B-Tree中,数据域可以包含任意类型的内容。数据库记录信息存储在数据域中。
3.3 B+Tree
- 表使用B+Tree定义在内部页面(
Internal Page
),不包含表数据(数据库记录)。
-
B+tree的根页面(Root Page)和内部节点页(Internal Page)都用于搜索导航。这些页中的数据域均指向下一层页,这些页只是包含键值。
-
在叶子页面(Leaf Page)。记录和页按照键值序排列,以便B-tree游标能够遍历记录(水平遍历)。是O(1)时间复杂度遍历记录成为可能。
以上是关于Sqlite pager和B-tree的运行机制的主要内容,如果未能解决你的问题,请参考以下文章