数据库索引实现原理—B_TREE
数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B_TREE。B_TREE索引加速了数据访问,因为存储引擎不会再去扫描整张表得到需要的数据;相反,它从根节点开始,根节点保存了子节点的指针,存储引擎会根据指针快速寻找数据。
上图显示了一种索引方式。左边是数据库中的数据表,有col1和col2两个字段,一共有15条记录;右边是以col2列为索引列的B_TREE索引,每个节点包含索引的键值和对应数据表地址的指针,这样就可以都过B_TREE在O(logn)的时间复杂度内获取相应的数据,这样明显地加快了检索的速度。
==============================================================================================================================
B_TREE(来源于数据结构,做个收藏)
1、B_TREE的定义
B_TREE是一种平衡多叉排序树,是一种动态查找效率很高的树形结构。B_TREE中所有结点的孩子结点的最大值称为B_TREE的阶,B_TREE的阶通常用m表示,简称为m叉树。一般来说,应该是m>=3。一颗m阶的B_TREE或是一颗空树,或者是满足下列条件的m叉树:
- 树中每个结点最多有m个孩子结点;
- 除根结点外,其它结点至少有(int)m/2+1个孩子结点;
- 若根结点不是叶子节点,则根结点至少有2个孩子结点;
- 结点的结构: 其中,n为结点中关键字个数,(int)m/2<=n<m;di(1<=i<=n)为该结点的n个关键字值的第i个,且di<d(i+1);ci(0<=i<=n)为该结点孩子结点的指针,且ci所指向的节点的关键字均大于或等于di且小于d(i+1);
- 所有的叶结点都在同一层上。
一棵4阶B_TREE的示例。4叉树结点的孩子结点的个数范围[2,4]。其中,有2个结点有4个孩子结点,有1个结点有3个孩子结点,有5个结点有2个孩子结点。
图 一棵4阶B_TREE
2、B_TREE的查找
在B_TREE上查找x,现将x的关键字与根结点的n个关键字di逐个比较,然后做如下处理:
- 若x.key==di,则查找成功返回;
- 若x.key<d1,则沿着指针c0所指的子树继续查找;
- 若di<x.key<d(i+1),则沿着指针ci所指的子树继续查找;
- 若x.key>dn,则沿着指针cn所指的子树继续查找。
3、B_TREE的插入
将元素x插入到B_TREE的过程为:
- 查找到x应该插入的结点(插入结点一定是叶结点);
- 判断该结点是否还有空位置,即判断该结点是否满足结点关键字的个数n小于m-1这个条件。若n<m-1,则说明该结点还有空位置,直接把数据插入(注意插入时要满足B_TREE结点结构定义);若n=m-1,则需要分裂该结点,即以中间关键字为界(包括要插入的关键字)把结点分为两个结点,并把中间元素向上插入到双亲结点,若双亲结点未满,则把它插入到双亲结点合适的位置,否则,继续往上分裂(直到根结点分裂可能会有树的高度增1的可能)。
4、B_TREE的删除
定义要删除结点x的关键字的个数为n,l=(int)m/2;
- 查找x是否存在,若不存在,则返回;若存在,则继续;
- 对于叶结点上的删除,分为3种情况:1、n>l则直接删除该数据元素;2、n=l且该结点左(右)兄弟结点关键字个数大于l,把删除数据元素结点的左(右)兄弟结点中最大(小)的元素上移到双亲结点上,同时把双亲结点中大于(小于)上移关键字的关键字下移到要删除数据元素的结点上;3、n=l且该结点左(右)兄弟结点关键字个数等于l,把要删除数据元素的结点的左(右)兄弟结点以及双亲结点上分割二者的数据元素合并成一个结点;
- 对于非叶结点的删除,可以转换为叶结点上的删除:假设要删除的元素为di,首先寻找要删除数据元素的结点的ci所指向子树中的最小关键字,设为d(min),然后把k(min)复制到ki,最后删除关键字为k(min)的元素(此时的k(min)必为某个叶结点上的元素)。