索引概述
索引(index)是一些能够帮助数据库系统高效查询数据的数据结构的统称
许多对表的查询只涉及表中很少的行,如找出学号是 114514 的学生的总学分,如果不借助索引,数据库系统就要读取表中每一行并检查其学号属性是否为 114514 ,这种方法无疑是低效的,而借助索引,我们可以通过某些方法直接定位到学号属性为 114514 的行
用于定位到待查询行的属性或属性集称作搜索码(search key)
索引的分类
数据结构
按数据结构分类,可以分为 B 树索引、B+ 树索引、散列索引等
主索引和辅助索引
被索引的表以文件的形式存放在磁盘中,如果文件中该表的行按某个搜索码指定的顺序排序,就把该搜索码对应的索引称作主索引(primary index),又叫聚集索引,其它搜索码对应的索引称作辅助索引(secondary index),又叫非聚集索引
通常情况下,一个表最多只有一个主索引,而辅助索引的个数没有限制
按主索引顺序对表进行顺序扫描要比按辅助索引顺序快很多,因为按主索引顺序扫描,需要访问的物理地址几乎是连续的
稠密索引和稀疏索引
如果表中在搜索码上的每一个值都对应一个索引项,则该索引称作稠密索引
如果表中在搜索码上只有部分值对应索引项,则该索引称作稀疏索引
辅助索引不能是稀疏索引,因为这样会导致没有索引项对应的搜索码值无法被定位到,而主索引如果是稀疏索引,可以先通过索引项定位到最接近待查询的搜索码值的行,然后从这行起在文件中逐行查找,直到找到待查询的搜索码值
索引的优缺点
优点
- 加快查询数据的速度
- 加快对表上唯一性约束检查的速度
- 加快表连接操作的速度
缺点
- 索引需要占用额外的空间
- 减慢了对表插入、删除、修改数据的速度,因为在执行这些操作时需要同时维护索引
B+ 树索引
B+ 树是一种多叉平衡树,和其它平衡树一样,B+ 树能够高效地增删数据和查询数据
用 B+ 树而不是二叉平衡树来实现索引的原因是:一张大表上的索引,其占用空间也很大,需要存放在磁盘而非内存中,多叉平衡树相比于二叉平衡树高度更低,一次操作所需要访问的节点数也更少,导致磁盘访问的次数更少,显然时间性能瓶颈在于磁盘访问耗时,因此 B+ 树相比于二叉平衡树,增删数据和查询数据更快
利用 B+ 树来维护搜索码值以及搜索码所在行的物理地址,我们就实现了 B+ 树索引
叶节点
B+ 树的叶节点结构如下:
P 1 P_1 P1 | K 1 K_1 K1 | P 2 P_2 P2 | K 2 K_2 K2 | ⋯ \cdots ⋯ | P n − 1 P_{n-1} Pn−1 | K n − 1 K_{n-1} Kn−1 | P n P_n Pn |
---|
其中 K 1 , K 2 , ⋯ , K n − 1 K_1,K_2, \cdots ,K_{n-1} K1,K2,⋯,Kn−1 是 n − 1 n-1 n−1 个搜索码,且对于 i ∈ [ 1 , n − 2 ] i \in [1,n-2] i∈[1,n−2] ,有 K i ≤ K i + 1 K_i \le K_{i+1} Ki≤Ki+1
对于 i ∈ [ 1 , n − 1 ] i \in [1,n-1] i∈[1,n−1] , P i P_i Pi 指向 K i K_i Ki 所在行的物理地址,而 P n P_n Pn 则指向 DFS 序顺序的下一个叶节点,对于按 DFS 序排序排在最后的叶节点,其 P n P_n Pn 指向按 DFS 序排序排在首位的叶节点,通常情况下,DFS 序越大的叶节点中的搜索码值越大
所有叶节点的高度相同,并且每个插入 B+ 树的搜索码,在所有叶节点中出现恰好一次
非叶节点
B+ 树的非叶节点结构和叶节点结构看起来一样, K 1 , K 2 , ⋯ , K n − 1 K_1,K_2, \cdots ,K_{n-1} K1,K2,⋯,Kn−1 仍是 n − 1 n-1 n−1 个有序的搜索码,但 P 1 , P 2 , ⋯ , P n P_1,P_2, \cdots ,P_n P1,P2,⋯,Pn 指向的东西不同
B+ 树的非叶节点中,