[Bツリーデータ構造]、B +ツリー説明

Bツリー

序文  

  まず第一に、なぜそれの知識のBツリー、B +ツリーをまとめる必要がありますか?最近の研究データベースのインデックスチューニング知識、データベース・システムは、一般的に使用されるB - / +ツリー索引構造として(例えば、MySQLのInnoDBエンジンは、B +ツリーを使用しています)、理解が徹底Bツリーではありませんが、あなたは、インデックス機構データベースを理解することはできません。次の最もシンプルかつBツリーデータ構造、B +ツリーの内容を理解するのは簡単

  さらに、B-ツリーは、ツリーはBです。Bツリーのオリジナルの英語名はBツリーで、国内のBツリー翻訳B-ツリーのような多くの人が、実際には、これは非常に悪い訳であるから、誤解しやすいです。通りの人々はBツリーは木の一種である一方、B-ツリーは、木だと思うかもしれません。そして実際に、B-treeがBツリー、バランスの取れたBの意味の現在の理解を指し、

  効率的なI / Oのための異なるストレージレベルとの間のアクセス速度に大きな差を埋めるように見えるBツリー 平衡二分木探索効率が非常に高く、木の深さを減らして効率を改善するために見ることができます。しかし、データが非常に大きい場合、ツリーの記憶素子の数が限られている、これはI / O読み、貧弱なクエリ効率につながる、あまりにも頻繁に書き込み過度のディスクによって引き起こされる木の深さに二分探索木構造の原因となります。さらにデータは、すべてのノードの平衡二分木の場合収容不足メモリ空間につながるすぎます。Bツリー構造のこの問題に良い解決策です

 

コンセプト

  まず、Bと木がバイナリツリーを混同していないコンピュータサイエンス、Bのツリーは、自己均衡あるツリーデータ構造命じたデータを維持し、可能に対数時間の検索、シーケンシャルアクセス、挿入および欠失を。Bツリーは二分探索木ノードつ以上の子ノードを有することができるので、一般化。[1]と他の異なる自己均衡二分探索木、Bは、データ(例えば、ディスク)ストレージシステムのツリー比較的大きなブロックを読み書きするのに非常に適しています。これは、一般的に使用されたデータベースファイルシステムを

 

定義

Bのマルチセクションツリーはバランスの取れた木である私たちは通常、m次のBツリーを言う、それは、以下の条件を満たしている必要があります。 

  • ほとんどの子ノードの各ノードメートル。
  • (ルートを除く)各非リーフノードは、少なくとも⌈M /2⌉子ノードを有しています。
  • ルートがリーフノードでない場合は、ルートには、少なくとも2人の子供がいます。
  • K子ノードの非リーフノードは、前記K  -1キーを。
  • すべての葉が同じレベル、ノー(同じ高さ)に表示されます。

どのような地獄を考えると、私はこの定義を見たのは初めて?オーダーとは何ですか?子ノード、葉のスポット、ルートを飛びますか?あなたは何を意味しています!ティーンエイジャーは、慌てる必要はありません。

Bツリーの順序は何ですか?

Mで表されるBツリーのノードに子ノードの最大数は、10の最大値場合、順序は、図10です。

すべてのノードは、子ノードの最大数は、4つの子ノード(灰色ノード)が持つノード[13,16,19]、あなたは第四次Bツリー上の画像を定義することができますので、今すぐバール程度であるかを理解

ルートとは何ですか?

[10]前記ルートノードである:ルートノードは、少なくとも2つのつの子ノードが(そうでなければ単一の容器になる)がある場合にのみ、ツリー内のノードではない場合、サブルートノードの同数は、上限と内部ノードを有しています。次いで、m次のBツリー(唯一の非ツリーのルートノード)、式2の関係<= M <= Mで、 Mは、 子ノードの数であり、1 <= K <= M-に含まれる要素の数 1は、Kであります要素の数。

内部ノードとは何ですか?

ノード[13,16,19]、[3,6]ノードが内部ノード、機能は次のとおりです。内部ノードは、葉ノード以外のすべてのノードであり、ルートノードは、親ノードと子ノードを持っています。内部ノードm次Bツリーの子ノードの数がMであると仮定すると、それは(M / 2)<= M満たさなければならない <= M M-1の要素の数を含む、関係を、格納されている要素の数を(M / 2) - 1 <= K <= M- 1、Kは、 要素の数です。M / 2が切り上げ。

リーフノードとは何ですか?

ノード[1,2]、[11]、及び他のノードは、最終的な層、リーフノードは、要素の数に同じ制限を有するリーフノードであるが、子ノードは、子ノードへのポインタが存在しません。前記ツリーのリーフノードコンプライアンス(M / 2)にm次のB要素-1 <= K <= M-1。

まあ、コンセプトが明らかになった、式をバック心配しないで、その後、見下します

 

挿入

何がある場合にm次Bツリーの高さhのために、要素はBツリーがあるかどうか、最初に、挿入されたとき、すなわち、リーフノードの最後に、新しい要素がリーフノードに挿入されていません。

  • ;ノード内の要素の数は、直接に、M-1未満である場合
  • ノード要素の数は、ノード分割を引き起こし、M-1に等しい場合、中間ノードを境界要素に、要素は、中央を取る(偶数二ランダム中間選択)親ノードに挿入されています。
  • 最悪のシナリオは、ルートノードに分割された、新しいルートを作成し、高さを1だけ増加され、Bツリーのルールに沿って、すべてのノードまでのアクションを繰り返します。

コア挿入操作、次のステップ5 Bツリー、例えば、詳細に挿入の動作を説明するための上記の3つの段落。

5次Bツリーのキーポイント:

  • ナンバー2 <=子ルートノード<= 5
  • 3 <数が子ノード= <= 5
  • 1 <=ルート要素の数<= 4
  • 2 <=非ルート要素の数<= 4

     8を挿入          

要素が[8]図なった後、(1)に挿入される。ルートノード要素5の数は、準拠していない場合(2)、  番号1 <=ルート要素<= 4、分割(真実は、第一部門であります次に繰り返さない、最初の直接の要素を挿入することである場合、次の操作が同じで、要素を挿入し)、中間要素ノードを取る(3に示すように[7])2つのノードに左右分割、親ノードに追加されます

(4)に示すように、素子[5]、[11]、[17]、任意の除算演算無しを挿入

   

要素を挿入する[13]

(6)に示されるように、それは、親ノードに挿入された中間要素抽出[13]、分割し、ノード内の要素の最大数を超え

    

 

 次いで、インサート要素は、[6]、[12]、[20]、[23]、任意の除算演算なしで、(7)に示すように

[26]挿入されると、空間の右端のリーフノードは、分割操作の必要満杯で、中間要素と親ノードに[20]、中間要素を移動させることにより、ノート、最終的に木、ノード分割の結果のバランスをとりますポイント2の重要な要素があります。

 

挿入されると[4]また、中間要素に起こる左端のリーフノードに至ることは、分割され[4]、親ノードが移動され、要素が[16]、[18]、[24]、[25]は連続して挿入されていますすべての除算なし

 

最後に、ときにインサートが[19]、[14]を含む、[16]、[17]、[18]親、親ノードに、しかし状況に移動する分割ノード、中間体[17]を必要とします空間ノードがいっぱいになることも分割されなければならない具体的な挿入操作が完了するように、中間要素は、新たに形成されたルートノードの[13]親ノードに移動されます。

 

削除

最初のツリー内のすべての要素の要素が、Bツリー、その削除されたノードで、次に要素中に存在する場合、削除するBを見つけるために、もしあれば要素を削除し、要素は、ノードが左の子を有するかどうか最初に決定され、その後、同様の要素(「右端の左の子ノード」または「右から左、最も子ノード」)親ノードの子ノードを上に移動し、移動後の状況は、そうでない場合は、それを削除します。

  • ノードは、隣人が満腹兄弟かどうかを確認するために必要とされる要素(M / 2)-1、(M / 2)切り上げ、数よりも少ないです。
  • 膨満場合(ノード要素(M / 2)-1の数よりも大きい場合)、次に親要素にノードが条件を満足します。
  • 如果其相邻兄弟都不丰满,即其结点数目等于(m/2)-1,则该结点与其相邻的某一兄弟结点进行“合并”成一个结点;

接下来还以5阶B树为例,详细讲解删除的动作;

  • 关键要领,元素个数小于 2(m/2 -1)就合并,大于4(m-1)就分裂

如图依次删除依次删除【8】,【20】,【18】,【5】

首先删除元素【8】,当然首先查找【8】,【8】在一个叶子结点中,删除后该叶子结点元素个数为2,符合B树规则,操作很简单,咱们只需要移动【11】至原来【8】的位置,移动【12】至【11】的位置(也就是结点中删除元素后面的元素向前移动)

 

 下一步,删除【20】,因为【20】没有在叶子结点中,而是在中间结点中找到,咱们发现他的继承者【23】(字母升序的下个元素),将【23】上移到【20】的位置,然后将孩子结点中的【23】进行删除,这里恰好删除后,该孩子结点中元素个数大于2,无需进行合并操作。

下一步删除【18】,【18】在叶子结点中,但是该结点中元素数目为2,删除导致只有1个元素,已经小于最小元素数目2,而由前面我们已经知道:如果其某个相邻兄弟结点中比较丰满(元素个数大于ceil(5/2)-1=2),则可以向父结点借一个元素,然后将最丰满的相邻兄弟结点中上移最后或最前一个元素到父节点中,在这个实例中,右相邻兄弟结点中比较丰满(3个元素大于2),所以先向父节点借一个元素【23】下移到该叶子结点中,代替原来【19】的位置,【19】前移;然【24】在相邻右兄弟结点中上移到父结点中,最后在相邻右兄弟结点中删除【24】,后面元素前移。

最后一步删除【5】, 删除后会导致很多问题,因为【5】所在的结点数目刚好达标,刚好满足最小元素个数(ceil(5/2)-1=2),而相邻的兄弟结点也是同样的情况,删除一个元素都不能满足条件,所以需要该节点与某相邻兄弟结点进行合并操作;首先移动父结点中的元素(该元素在两个需要合并的两个结点元素之间)下移到其子结点中,然后将这两个结点进行合并成一个结点。所以在该实例中,咱们首先将父节点中的元素【4】下移到已经删除【5】而只有【6】的结点中,然后将含有【4】和【6】的结点和含有【1】,【3】的相邻兄弟结点进行合并成一个结点。

 

也许你认为这样删除操作已经结束了,其实不然,在看看上图,对于这种特殊情况,你立即会发现父节点只包含一个元素【7】,没达标(因为非根节点包括叶子结点的元素K必须满足于2=<K<=4,而此处的K=1),这是不能够接受的。如果这个问题结点的相邻兄弟比较丰满,则可以向父结点借一个元素。而此时兄弟节点元素刚好为2,刚刚满足,只能进行合并,而根结点中的唯一元素【13】下移到子结点,这样,树的高度减少一层。

看完插入,删除,想必也把B树的特征掌握了,下面普及下其他知识,换个脑子

 

 

磁盘IO与预读

  计算机存储设备一般分为两种:内存储器(main memory)和外存储器(external memory)。 

  内存储器为内存,内存存取速度快,但容量小,价格昂贵,而且不能长期保存数据(在不通电情况下数据会消失)。

  外存储器即为磁盘读取,磁盘读取数据靠的是机械运动,每次读取数据花费的时间可以分为寻道时间、旋转延迟、传输时间三个部分,寻道时间指的是磁臂移动到指定磁道所需要的时间,主流磁盘一般在5ms以下;旋转延迟就是我们经常听说的磁盘转速,比如一个磁盘7200转,表示每分钟能转7200次,也就是说1秒钟能转120次,旋转延迟就是1/120/2 = 4.17ms;传输时间指的是从磁盘读出或将数据写入磁盘的时间,一般在零点几毫秒,相对于前两个时间可以忽略不计。那么访问一次磁盘的时间,即一次磁盘IO的时间约等于5+4.17 = 9ms左右,听起来还挺不错的,但要知道一台500 -MIPS的机器每秒可以执行5亿条指令,因为指令依靠的是电的性质,换句话说执行一次IO的时间可以执行40万条指令,数据库动辄十万百万乃至千万级数据,每次9毫秒的时间,显然是个灾难。下图是计算机硬件延迟的对比图,供大家参考:

   考虑到磁盘IO是非常高昂的操作,计算机操作系统做了一些优化,当一次IO时,不光把当前磁盘地址的数据,而是把相邻的数据也都读取到内存缓冲区内,因为局部预读性原理告诉我们,当计算机访问一个地址的数据的时候,与其相邻的数据也会很快被访问到。每一次IO读取的数据我们称之为一页(page)。具体一页有多大数据跟操作系统有关,一般为4k或8k,也就是我们读取一页内的数据时候,实际上才发生了一次IO,这个理论对于索引的数据结构设计非常有帮助。

事实1 : 不同容量的存储器,访问速度差异悬殊。

  • 磁盘(ms级别) << 内存(ns级别), 100000倍
  • 若内存访问需要1s,则一次外存访问需要一天
  • 为了避免1次外存访问,宁愿访问内存100次...所以将最常用的数据存储在最快的存储器中

事实2 : 从磁盘中读 1 B,与读写 1KB 的时间成本几乎一样

从以上数据中可以总结出一个道理,索引查询的数据主要受限于硬盘的I/O速度,查询I/O次数越少,速度越快,所以B树的结构才应需求而生;B树的每个节点的元素可以视为一次I/O读取,树的高度表示最多的I/O次数,在相同数量的总元素个数下,每个节点的元素个数越多,高度越低,查询所需的I/O次数越少;假设,一次硬盘一次I/O数据为8K,索引用int(4字节)类型数据建立,理论上一个节点最多可以为2000个元素,2000*2000*2000=8000000000,80亿条的数据只需3次I/O(理论值),可想而知,B树做为索引的查询效率有多高;

另外也可以看出同样的总元素个数,查询效率和树的高度密切相关

 

B树的高度

一棵含有N个总关键字数的m阶的B树的最大高度是多少?

  log(m/2)(N+1)/2 + 1  ,log以(m/2)为低,(N+1)/2的对数再加1

算法如下

 

 

 

B+树

   B+树是应文件系统所需而产生的B树的变形树,那么可能一定会想到,既然有了B树,又出一个B+树,那B+树必然是有很多优点的

 

B+树的特征:

  • 有m个子树的中间节点包含有m个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引;
  • 所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接。 (而B 树的叶子节点并没有包括全部需要查找的信息);
  • 所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B 树的非终节点也包含需要查找的有效信息);

 

为什么说B+树比B树更适合数据库索引?

1)B+树的磁盘读写代价更低

  B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了;

2)B+树查询效率更加稳定

  非エンドポイントは、ファイルの終点ノードの内容が、キーワードで唯一の索引リーフ・ノードではありませんので。だから、任意のキーワードを探すことはリーフノードへのルートからのパスに従わなければなりません。キーワードクエリと同じ長さのすべてのパス、各データのかなりの効率でクエリ結果。

3)B +ツリーは、(最も重要な理由は、通常のデータベースの範囲を見つけることである)範囲クエリを容易に

  B-treeは正確に私たちのために、この問題は、B +ツリーのアプリケーションを解決するために、IO性能を向上させると同時に、私が通過する要素の効率が低いという問題を解決していません。B +ツリーのリーフ・ノードは、ちょうどツリー全体を横断を達成することができトラバースする必要があります。そして、データベースクエリの範囲で非常に頻繁に基づいており、B-treeがこのような操作や非効率的に対応していません。この解釈を見ることができます理解していない- " 検索レンジ

 

注:範囲Bのルックアップツリートラバーサルシーケンスを使用して、リスト上のB +ツリートラバーサルを使用しました。

次のB +ツリーとして:

 

おすすめ

転載: www.cnblogs.com/lianzhilei/p/11250589.html