目录
mysql 索引数据结构:
B+tree 索引是B+树在数据库中的一种实现,最为常见的。B+树 中的B代表平衡,而不是二叉
1、二叉查找树
二叉树的左子树的键值小于根的键值,右子树的键值大于根的键值。
二叉查找树可以任意构造,但是可能有些构造情况可能导致查找效率低。如果想让二叉树查询效率尽可能的高,需要二叉树是平衡的,所以有AVL平衡二叉树
2、平衡二叉树AVL Tree
合二叉树的条件,还满足任何节点两个子树的高度最大差为1.
AVL树进行插入或删除节点,可能导致AVL树失去平衡,会出现:左左,左右,右左、右右的情况,会导致失去平衡,就需要进行旋转。
3 、平衡多叉树B-Tree
B-Tree是为磁盘等待外存设备设计的一种平衡查找树。每个节点包含key和data.
系统从磁盘读取数据到内存时以磁盘块block为基本耽误的,位于同一个磁盘块中的数据会被一次性读取出来,不是需要什么取取什么。InnoDB存储引擎中有页Page,页也是磁盘管理的最小耽误。InnoDB存储引擎中默认每个页大小为16KB,通过innodb_page_size将页大小设置为4k\8k\16k.
InnoDB在把磁盘数据读入搭配磁盘时会以页为基本单位,查询时如果每一页中每条数据都能有助于定位数据记录的位置,将会减少IO次数,提高查询效率。
B-Tree是键值对进行记录,key各不相同。m阶的B-Tree特性为:
1)每个节点最多有m个孩子。
2)除了根节点和叶子节点外,其他每个节点至少有 (m+1)/2个孩子;
3)若根节点不是叶子节点,则至少有2个孩子;
4)所有叶子节点都在同一层,且不包含其他关键字的信息。
5)每个非中断节点包含n个关键字信息;
6)ki为关键字,且关键字升序排列
模拟查找关键字29的过程:
- 根据根节点找到磁盘块1,读入内存。【磁盘I/O操作第1次】
- 比较关键字29在区间(17,35),找到磁盘块1的指针P2。
- 根据P2指针找到磁盘块3,读入内存。【磁盘I/O操作第2次】
- 比较关键字29在区间(26,30),找到磁盘块3的指针P2。
- 根据P2指针找到磁盘块8,读入内存。【磁盘I/O操作第3次】
- 在磁盘块8中的关键字列表中找到关键字29。
分析上面过程,发现需要3次磁盘I/O操作,和3次内存查找操作。由于内存中的关键字是一个有序表结构,可以利用二分法查找提高效率。而3次磁盘I/O操作是影响整个B-Tree查找效率的决定因素。B-Tree相对于AVLTree缩减了节点个数,使每次磁盘I/O取到内存的数据都发挥了作用,从而提高了查询效率。
4、B+Tree树
在B-Tree基础上进行优化,使其更适合实现外存储索引结构。InnoDB就是存储引擎就是用B+Tree。
在B-Tree中每一个页存储空间有限,如果data数据较大,会导致每个节点key太小,当数据量很大同一会导致B_Tree深度较大,增大查询的磁盘IO次数,影响查询效率。
在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层叶子节点上,而非叶子节点上只存储key值信息,可以大大增大每个节点存储的key值的数量,降低B+Tree的高度。
特点:
1)非叶子节点只存储键值信息;
2)所有叶子节点之间都有一个链指针;
3)数据记录都存放在叶子节点中;
B+Tree有两个头指针,一个指向根节点,一个指向关键字最小的叶子节点,而且所有叶子节点即数据节点之间是一个链式环。
B+Tree树,对B+Tree的查找运算:对于主键的范围查找和分页查找;从根节点开始,进行随机查找。
数据库中B+Tree索引可以为聚集索引和辅助索引。
上图为聚集索引,(主键)聚集索引的B+Tree的叶子节点存放的整张表的行记录数据。辅助索引和聚集索引的区别在于辅助索引的叶子节点并不包含行记录的全部数据,二十存储相应行数据的聚集索引,即主键。当通过辅助索引来查询数据时,InnoDB存储引擎会遍历辅助索引找到主键,然后再通过主键在聚集索引中找到完整的行记录数据。
无序的字符: mysql 可以使用ASSIC 进行比较大小;
5 、红黑树
R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。
红黑规则
- 节点不是黑色,就是红色(非黑即红)
- 根节点为黑色
- 叶节点为黑色(叶节点是指末梢的空节点
Nil
或Null
)
- 一个节点为红色,则其两个子节点必须是黑色的(根到叶子的所有路径,不可能存在两个连续的红色节点)
- 每个节点到叶子节点的所有路径,都包含相同数目的黑色节点(相同的黑色高度)
红黑树的应用
- Java中,TreeMap、TreeSet都使用红黑树作为底层数据结构
- JDK 1.8开始,HashMap也引入了红黑树:当冲突的链表长度超过8时,自动转为红黑树
- Linux底层的CFS进程调度算法中,vruntime使用红黑树进行存储。
- 多路复用技术的Epoll,其核心结构是红黑树 + 双向链表 ;; redis io多路复用
红黑树的 查询性能略微逊色于AVL树,因为他比avl树会稍微不平衡最多一层,也就是说红黑树的查询性能只比相同内容的avl树最多多一次比较,但是,红黑树在插入和删除上完爆avl树, avl树每次插入删除会进行大量的平衡度计算,而红黑树为了维持红黑性质所做的红黑变换和旋转的开销,相较于avl树为了维持平衡的 开销要小得多;
红黑树的每个节点只能存放一个元素
6.平衡树的旋转
旋转的目的是为了保持树的平衡; 平衡的条件: 左右子树高度差不超过1;
- 左旋转
- 在右子树添加节点造成不平衡。root只有右孩子的情况,以root的右孩子为中心,向左(逆时针)旋转root节点,旋转结果为root节点变为root右孩子的左孩子,如下图, 在右子树添加节点(图中的16),造成不平衡
- 在右子树添加节点造成不平衡,其中root同时有左右子树,左子树只有一个节点,右孩子只有一个右子节点,添加一个节点(下图中的17)后造成不平衡树,此时可以看到,root的右子树不平衡,此时按照第一种旋转方式可以将右子树旋转平衡,进而使整棵树平衡,
- 在右子树添加节点造成不平衡,其中root只有一个左孩子,root的右孩子同时存在左右孩子,
2.右旋转
- 在左子树添加节点造成不平衡, root没有右孩子,同时左孩子只有左孩子一个节点, 此时以root的左孩子为中心,进行右旋转(顺时针旋转), 将root左孩子提升为root,root降为左孩子的右孩子,
- 在左子树添加节点造成不平衡, root同时包含左右孩子,右孩子没有子节点,左孩子只有一个左孩子节点,此时root的左子树为不平衡树,按照上面的方式对左子树进行右旋转得到平衡树,
- 在左子树添加节点造成不平衡, root只有一个右孩子, 左孩子同时有左右孩子, 在左孩子的左孩子下添加一个节点,