澳门皇冠金沙网站-澳门皇冠844网站

热门关键词: 澳门皇冠金沙网站,澳门皇冠844网站

转载和笔记

  B-Tree就是我们常说的B树,一定不要读成B减树,否则就很丢人了。B树这种数据结构常常用于实现数据库索引,因为它的查找效率比较高。

索引使用和优化还没看

聚集索引和非聚集索引结构参考:

磁盘IO与预读

磁盘读取依靠的是机械运动,分为寻道时间、旋转延迟、传输时间三个部分,这三个部分耗时相加就是一次磁盘IO的时间,大概9ms左右。这个成本是访问内存的十万倍左右;正是由于磁盘IO是非常昂贵的操作,所以计算机操作系统对此做了优化:预读;每一次IO时,不仅仅把当前磁盘地址的数据加载到内存,同时也把相邻数据也加载到内存缓冲区中。因为局部预读原理说明:当访问一个地址数据的时候,与其相邻的数据很快也会被访问到。每次磁盘IO读取的数据我们称之为一页(page)。一页的大小与操作系统有关,一般为4k或者8k。这也就意味着读取一页内数据的时候,实际上发生了一次磁盘IO。

归纳要点:索引是数据结构。为什么使用索引,从计算机存储原理去考虑------胖树-(B树和B 树)。B树的原理,结合计算机存储原理知道了为什么B树性能好。MySQL中MyISAM和InnoDB都使用了B 树,有什么不同(聚集索引和非聚集索引),辅助索引有什么不同。

前两天有位朋友邀请我回答个问题,为什么 MongoDB (索引)使用B-树而 Mysql 使用 B 树?我觉得这个问题非常好,从实际应用的角度来学习数据结构,没有比这更好的方法了。因为像 Mysql 和 MongoDB 这种经久考验的大型软件在设计上都是精益求精的,它们为什么选择这些数据结构?:)

B-Tree与二叉查找树的对比

  我们知道二叉查找树查询的时间复杂度是O(logN),查找速度最快和比较次数最少,既然性能已经如此优秀,但为什么实现索引是使用B-Tree而不是二叉查找树,关键因素是磁盘IO的次数。

数据库索引是存储在磁盘上,当表中的数据量比较大时,索引的大小也跟着增长,达到几个G甚至更多。当我们利用索引进行查询的时候,不可能把索引全部加载到内存中,只能逐一加载每个磁盘页,这里的磁盘页就对应索引树的节点。

根据原理得出索引的使用和优化(这个还没看)

本文从实际应用的角度来介绍以及分析B-树和B 树。

一、 二叉树

我们先来看二叉树查找时磁盘IO的次:定义一个树高为4的二叉树,查找值为10:

                                                            图片 1

 

第一次磁盘IO:

                         图片 2

 

 

 第二次磁盘IO

                           图片 3

 

第三次磁盘IO:

                             图片 4

 

第四次磁盘IO:

                                   图片 5

从二叉树的查找过程了来看,树的高度和磁盘IO的次数都是4,所以最坏的情况下磁盘IO的次数由树的高度来决定。

从前面分析情况来看,减少磁盘IO的次数就必须要压缩树的高度,让瘦高的树尽量变成矮胖的树,所以B-Tree就在这样伟大的时代背景下诞生了。

转载和笔记:MySQL索引背后的数据结构及算法原理


二、B-Tree

m阶B-Tree满足以下条件:

1、每个节点最多拥有m个子树

2、根节点至少有2个子树

3、分支节点至少拥有m/2颗子树(除根节点和叶子节点外都是分支节点)

4、所有叶子节点都在同一层、每个节点最多可以有m-1个key,并且以升序排列

 如下有一个3阶的B树,观察查找元素21的过程:

                                                                              图片 6

第一次磁盘IO:     

                                                           图片 7

第二次磁盘IO:

                                                  图片 8

这里有一次内存比对:分别跟3与12比对

第三次磁盘IO:

                                                     图片 9

这里有一次内存比对,分别跟14与21比对

从查找过程中发现,B树的比对次数和磁盘IO的次数与二叉树相差不了多少,所以这样看来并没有什么优势。

但是仔细一看会发现,比对是在内存中完成中,不涉及到磁盘IO,耗时可以忽略不计。另外B树种一个节点中可以存放很多的key(个数由树阶决定)。

相同数量的key在B树中生成的节点要远远少于二叉树中的节点,相差的节点数量就等同于磁盘IO的次数。这样到达一定数量后,性能的差异就显现出来了。

漫画:什么是B-树?

B-树由来

定义:B-树是一类树,包括B-树、B 树、B*树等,是一棵自平衡的搜索树,它类似普通的平衡二叉树,不同的一点是B-树允许每个节点有更多的子节点。B-树是专门为外部存储器设计的,如磁盘,它对于读取和写入大块数据有良好的性能,所以一般被用在文件系统及数据库中。

定义只需要知道B-树允许每个节点有更多的子节点即可。子节点数量一般在上千,具体数量依赖外部存储器的特性。

先来看看为什么会出现B-树这类数据结构。

传统用来搜索的平衡二叉树有很多,如 AVL 树,红黑树等。这些树在一般情况下查询性能非常好,但当数据非常大的时候它们就无能为力了。原因当数据量非常大时,内存不够用,大部分数据只能存放在磁盘上,只有需要的数据才加载到内存中。一般而言内存访问的时间约为 50 ns,而磁盘在 10 ms 左右。速度相差了近 5 个数量级,磁盘读取时间远远超过了数据在内存中比较的时间。这说明程序大部分时间会阻塞在磁盘 IO 上。那么我们如何提高程序性能?减少磁盘 IO 次数,像 AVL 树,红黑树这类平衡二叉树从设计上无法“迎合”磁盘。 

图片 10

上图是一颗简单的平衡二叉树,平衡二叉树是通过旋转来保持平衡的,而旋转是对整棵树的操作,若部分加载到内存中则无法完成旋转操作。其次平衡二叉树的高度相对较大为 log n(底数为2),这样逻辑上很近的节点实际可能非常远,无法很好的利用磁盘预读(局部性原理),所以这类平衡二叉树在数据库和文件系统上的选择就被 pass 了。

空间局部性原理:如果一个存储器的某个位置被访问,那么将它附近的位置也会被访问。

我们从“迎合”磁盘的角度来看看B-树的设计。

索引的效率依赖与磁盘 IO 的次数,快速索引需要有效的减少磁盘 IO 次数,如何快速索引呢?索引的原理其实是不断的缩小查找范围,就如我们平时用字典查单词一样,先找首字母缩小范围,再第二个字母等等。平衡二叉树是每次将范围分割为两个区间。为了更快,B-树每次将范围分割为多个区间,区间越多,定位数据越快越精确。那么如果节点为区间范围,每个节点就较大了。所以新建节点时,直接申请页大小的空间(磁盘是按 block 分的,一般为 512 Byte。磁盘 IO 一次读取若干个 block,我们称为一页,具体大小和操作系统有关,一般为 4 k,8 k或 16 k),计算机内存分配是按页对齐的,这样就实现了一个节点只需要一次 IO。

图片 11

上图是一棵简化的B-树,多叉的好处非常明显,有效的降低了B-树的高度,为底数很大的 log n,底数大小与节点的子节点数目有关,一般一棵B-树的高度在 3 层左右。层数低,每个节点区确定的范围更精确,范围缩小的速度越快。上面说了一个节点需要进行一次 IO,那么总 IO 的次数就缩减为了 log n 次。B-树的每个节点是 n 个有序的序列(a1,a2,a3…an),并将该节点的子节点分割成 n 1 个区间来进行索引(X1< a1, a2 < X2 < a3, … , an 1 < Xn < anXn 1 > an)。


 三、B树的新增

在刚才的基础上新增元素4,它应该在3与9之间:

                                 图片 12

                                     图片 13

                                     图片 14

 

漫画:什么是B 树?

B-树

图片 15

上图是一颗B-树,B-树的每个节点有 d~2d 个 key,2 这个因子指明了树的分裂及合并的规则,这个规则维持了B-树的平衡。

B-树的插入和删除就不具体介绍了,很多资料都描述了这一过程。在普通平衡二叉树中,插入删除后若不满足平衡条件则进行 旋转 操作,而在B-树中,插入删除后不满足条件则进行分裂及合并操作。

简单叙述下分裂及合并操作。

分裂:如果有一个节点有 2d 个 key,增加一个后为 2d 1 个 key,不符合上述规则 B-树的每个节点有 d~2d 个 key,大于 2d,则将该节点进行分裂,分裂为两个 d 个 key 的节点并将中值 key 归还给父节点。 
合并:如果有一个节点有 d 个 key,删除一个后为 d-1 个 key,不符合上述规则 B-树的每个节点有 d~2d 个 key,小于 d,则将该节点进行合并,合并后若满足条件则合并完成,不满足则均分为两个节点。

B-树的查找

我们来看看B-树的查找,假设每个节点有 n 个 key值,被分割为 n 1 个区间,注意,每个 key 值紧跟着 data 域,这说明B-树的 key 和 data 是聚合在一起的。一般而言,根节点都在内存中,B-树以每个节点为一次磁盘 IO,比如上图中,若搜索 key 为 25 节点的 data,首先在根节点进行二分查找(因为 keys 有序,二分最快),判断 key 25 小于 key 50,所以定位到最左侧的节点,此时进行一次磁盘 IO,将该节点从磁盘读入内存,接着继续进行上述过程,直到找到该 key 为止。

查找伪代码

Data* BTreeSearch(Root *node, Key key)
{
    Data* data;

    if(root == NULL)
        return NULL;
    data = BinarySearch(node);
    if(data->key == key)
    {
        return data;
    }else{
        node = ReadDisk(data->next);
        BTreeSearch(node, key);
    }
}

四、B树的删除

 删除元素9:

                                  图片 16

 

                                    图片 17

码农翻身课堂讲解

B 树

B 树是B-树的变种,它与B-树的不同之处在于:

  • 在B 树中,key 的副本存储在内部节点,真正的 key 和 data 存储在叶子节点上 。
  • n 个 key 值的节点指针域为 n 而不是 n 1。

如下图为一颗B 树:

图片 18

因为内节点并不存储 data,所以一般B 树的叶节点和内节点大小不同,而B-树的每个节点大小一般是相同的,为一页。

为了增加 区间访问性,一般会对B 树做一些优化。 
如下图带顺序访问的B 树。

图片 19


五、总结

  插入或者删除元素都会导致节点发生裂变反应,有时候会非常麻烦,但正因为如此才让B树能够始终保持多路平衡,这也是B树自身的一个优势:自平衡;B树主要应用于文件系统以及部分数据库索引,如MongoDB,大部分关系型数据库索引则是使用B 树实现。

 

 

摘要

MySQL数据库支持多种所应类型,如Btree索引,哈希索引,全文索引等等。BTree索引,平常使用MySQL时主要打交道的索引。

B*树:在B 树基础上,为非叶子结点也增加链表指针

数据结构及算法基础

索引是什么:索引(Index)是帮助MySQL高效获取数据的数据结构。索引本质:数据结构。

为什么需要索引:使查询数据的速度尽可能快。

怎么快:从查询算法角度优化。常见的查询算法如下:


顺序查找 :顺序地检查列表的每个元素,直到找到与目标值匹配的元素。如果算法到达列表的末尾,搜索将失败。 时间复杂度:O(n)

二分查找:时间复杂度O(log N)  局限性:要求被检索数据有序

图片 20

二分查找示意图

二叉树查找:局限性 同样的一组数据,输入的顺序不同,二叉树的高度不同,太高的树可能有太多的IO操作。

图片 21

一组数据用不同的输入顺序得到不同的二叉查找树

二叉查找树与索引:

图片 22

二叉查找树和索引 案例

上图展示了一种可能的索引方式。左边是数据表,一共有两列六条记录,最左边的是数据记录的物理地址(注意逻辑上相邻的记录在磁盘上也并不是一定物理相邻的)。为了加快Age的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在O(log2n)的复杂度内获取到相应数据。

虽然这是一个货真价实的索引,但是实际的数据库系统几乎没有使用二叉查找树或其进化品种红黑树(red-black tree)实现的,原因与IO操作有关。

Select * from users where age >= 24 and age <=93  (范围查找无法解决)


图片 23

 

本文由澳门皇冠金沙网站发布于数据库研究,转载请注明出处:转载和笔记