基本概念
主码
主码时数据库中的每条记录的唯一标识,只有主码不便于各种灵活检索
辅码
数据库中可以出现重复值的码(属性)
辅码索引把一个辅码值与具有这个辅码值的多条记录的主码值关联起来
索引
把关键码与他对应的记录位置关联起来的过程,建立==(关键码,指针)对,即(key,pointer)==,指针指向主数据库文件中的完整记录
索引文件
索引文件是指用于记录这种联系的文件,一个主文件可能有多个相关索引文件,通过索引文件可以高效访问记录中的关键码
稠密索引与稀疏索引
稠密索引:对每个记录建立一个索引项
- 特点:主文件不需要按关键码次序排列
稀疏索引:对一组记录建立一个索引项
- 特点:主文件必须按照关键码次序排列,可以把记录分成多个组
线性索引
按照索引码值的顺序进行排序的文件,索引文件上的指针指向存储在磁盘上的文件记录起始位置或者主索引中主码的起始位置
优点:可以对变长数据库记录访问,通过二分检索支持对数据的高效检索
缺点:线性索引太大,需要存储在磁盘中
二级线性索引
对一级线性索引的若干个磁盘块建立一个二级索引,二级索引的指针指向相应磁盘块的起始位置,关键码与相应磁盘块中第一条记录的关键码值相同
在检索时先把二级线性索引文件读入内存,根据二分查找关键码找到对应的一级文件索引的磁盘块,并将其读入内存,然后再按照二分检索的办法找到记录在磁盘上的位置,最后把所需记录读入,便完成了检索的操作
静态索引
索引结构在文件创建时生成,一旦生成就固定下来,在插入和删除过程中索引结构不改变,一般使用多分树来实现
使用多分树能大大减少访问外存的次数
倒排索引
按属性值建立索引,索引表中的每一项包括一个属性值和具有该属性值的各关键码或记录地址
由属性值来确定记录的位置,称为倒排索引
带有倒排索引的文件称为倒排文件
分类
- 基于属性的倒排
- 对于正文文件的倒排
基于属性的倒排
按属性值建立起来索引表,称为倒排表,包括属性值和记录指针两个元素,记录指针可以是关键码,或该记录的主文件地址
优劣
优点:支持基于属性的高效检索
缺点:花费了保存倒排表的存储代价,降低了更新运算的效率
对正文文件的倒排
正文索引:支持对文本内容的快速检索
词索引
从正文中抽取关键词,然后用这些关键词组成适合快速检索的数据结构
- 对于中文需要切词处理
全文索引
正文看作一个长的字符串,记录每个字符串的开始位置,查询可以针对正文中的任何字符串进行
- 可以对每个字符串建立索引,从而使查询不再限于关键词
- 索引结构将耗费更大的空间
建立正文倒排文件
- 对文档集中的所有文件都进行分割处理,把正文分成多条记录文档
- 各每条记录赋一组关键词
- 建立正文倒排表、倒排文件
优劣
优点:高效检索,用于文本数据库系统
缺点:支持的检索类型有限,需要的空间代价往往很高
动态索引
动态索引结构:文件创建时生成,结构随着插入、删除等操作而改变
目的:保持最佳的检索性能
B树
m阶B树是一棵m路查找树,或者为空,或者
- 上界:每个结点最多有m个子结点
- 根结点至少有2棵子树,其它非叶结点至少有 ⌈ m 2 ⌉ \lceil\frac m2\rceil ⌈2m⌉
- 有k棵子树的结点有k-1个关键码
- 叶结点都位于同一层,有 ⌈ m 2 ⌉ − 1 到 m − 1 \lceil\frac m2\rceil-1到m-1 ⌈2m⌉−1到m−1个关键码
B树的结点包含j个关键码,j+1个 指针的结点
- Ki是关键码值,K1<K2<…<Kj
- Pi是指向包括Ki到Ki+1之间的关键码的子树的指针
性质
- 树高平衡、叶结点同层、关键码不重复
- 父结点关键码是子结点的分界
- 具有K个子结点的结点包含k-1个关键码
- 访问局部性原理
- 结点的关键码至少一定比例是满的
查找
读取根结点,在包含的关键码中查找给定的关键码,找到则检索成功
否则确定要查的关键码值是在某个Ki和Ki+1之间,于是取pi所指向的结点继续查找
如果pi指向外部空结点,表示检索失败
检索长度
设高为h(独根树高度为1),在自顶向下检索到叶结点的过程中可能需要进行h次读盘,最多需要h+1次访问外存
插入
找到最底层插入,若溢出,则结点分裂,中间关键码连同新指针插入父结点,若父结点也溢出,则继续分裂(分裂过程可能传达到根结点,导致树升高一层)
分裂:结点p分裂成p和q两个结点,假设中间的关键码为 K ⌈ m 2 ⌉ K_{\lceil\frac m2\rceil} K⌈2m⌉,该值与q指针形成一个新的二元组,插入到这个结点的父结点中去
删除
若删除的关键码不在叶结点层,先把关键码与它在B树的后继对换位置,然后再删除该关键码
若删除后关键码个数不小于 ⌈ m 2 ⌉ − 1 \lceil\frac m2\rceil-1 ⌈2m⌉−1,则直接删除
若删除后关键码个数小于 ⌈ m 2 ⌉ − 1 \lceil\frac m2\rceil-1 ⌈2m⌉−1
- 若兄弟结点的管家那么个数大于 ⌈ m 2 ⌉ − 1 \lceil\frac m2\rceil-1 ⌈2m⌉−1,则借若干个关键码(父结点中的分界关键码要做调整)
- 如果兄弟结点关键码个数等于 ⌈ m 2 ⌉ − 1 \lceil\frac m2\rceil-1 ⌈2m⌉−1,则合并
性能
包含N个关键码的B树,有N+1个外部指针,假设外部指针在第k层,第0层根至少1个结点,第1层至少2个结点,第2层至少 2 ⋅ ⌈ m 2 ⌉ 2\cdot\lceil\frac m2\rceil 2⋅⌈2m⌉个结点,第k层至少 2 ⋅ ⌈ m 2 ⌉ k − 1 2\cdot\lceil\frac m2\rceil^{k-1} 2⋅⌈2m⌉k−1个结点
N + 1 ≥ 2 ⋅ ⌈ m 2 ⌉ k − 1 , k ≤ 1 + log ⌈ m 2 ⌉ N + 1 2 N+1\ge2\cdot\lceil\frac m2\rceil^{k-1},k\le1+\log_{\lceil\frac m2\rceil}\frac{N+1}2 N+1≥2⋅⌈2m⌉k−1,k≤1+log⌈2m⌉2N+1
设内部结点数为p,当根包含一个关键码时,除根外的所有内部结点都包含 ⌈ m 2 ⌉ − 1 \lceil\frac m2\rceil-1 ⌈2m⌉−1时,B树包含的关键码的个数最少 N ≥ 1 + ( ⌈ m 2 ⌉ − 1 ) ( p − 1 ) N\ge1+(\lceil\frac m2\rceil-1)(p-1) N≥1+(⌈2m⌉−1)(p−1),即 p − 1 ≤ N − 1 ⌈ m 2 ⌉ − 1 p-1\le\frac{N-1}{\lceil\frac m2\rceil-1} p−1≤⌈2m⌉−1N−1
除第1个结点外,剩余的p-1个结点都是分裂而来的,则每插入一个关键码平均分裂结点个数为
s
=
p
−
1
N
−
1
≤
N
−
1
(
⌈
m
2
⌉
−
1
)
(
N
−
1
)
=
1
⌈
m
2
⌉
−
1
s=\frac{p-1}{N-1}\le\frac{N-1}{(\lceil\frac m2\rceil-1)(N-1)}=\frac1{\lceil\frac m2\rceil-1}
s=N−1p−1≤(⌈2m⌉−1)(N−1)N−1=⌈2m⌉−11
B+树
B+树是B树的一种变形,在叶结点上存储信息的树,所有关键码均在叶结点上,各层结点中的关键码均是下一层相应结点总最大关键码(或最小关键码)的复写
每个节点至少有 ⌈ m 2 ⌉ \lceil\frac m2\rceil ⌈2m⌉个子结点(根除外),至多有m个子结点,根结点至少有两个子结点(根为空和独根树除外),有k个子结点必有k个关键码
B+树和B树的差异
B+树中的n棵子树的结点中含有n个关键码,而B树中n棵子树的结点中含有n-1个关键码
B+树叶子结点包含了完整的索引信息,而B树所有结点共同构成全部索引信息
B+树所有的非叶子结点可以看成是高层索引,结点中仅含有其子树中最大(或最小的关键码)
B+树的查找
- 查找到叶结点层
- 在上层已找到待查的关键码,并不停止
- 继续沿指针向下查到叶结点层这个关键码
- B+树叶结点一般链接起来,形成一个双链表
- 适合顺序检索(范围检索)
- 实际应用更广
B+树的插入
过程和B树类似,分裂为左 ⌈ m 2 ⌉ \lceil\frac m2\rceil ⌈2m⌉和右 ⌈ m 2 ⌉ \lceil\frac m2\rceil ⌈2m⌉,注意保证上一层结点中有这两个结点的最大关键码(或最小关键码)
B+树的删除
当删除结点后关键码个数越下界,与左兄弟进行调整、合并处理,与B树类似
红黑树
红黑树内容较多所以单独分出来了一篇
红黑树