ポイントBツリーはどのように我々は徹底的にデータベースインデックスの基本原則を理解することができ、気にしませんでしたか?

バイナリツリー(バイナリ検索ツリー)

バイナリツリーは、各ノードは最大2つのサブ木のツリー構造を有しています。サブツリーは、一般的に「左の部分木」(左サブツリー)と「右部分木」(右サブツリー)と呼ばれます。バイナリツリーは、多くの場合、バイナリ検索ツリーとバイナリヒープを実装するために使用されます。

バイナリツリーは、次の機能があります。

  • 各ノードはサブツリー要素及びN、0≤n≤2含ま。

  • 左サブツリーと右サブツリーが順序である、順序は任意に戻すことはできません。値は、左サブツリーの親ノードである未満で、値は、親ノードの右サブツリーよりも大きいです。

ビットルックコンセプトボーリング、我々は今、数字のようなセットを持っていると仮定[35274812293855]、シーケンス番号は、以下のステップ、構造に挿入されています。

まあ、これは、バイナリツリーです!私たちは、挿入操作の一連の後、無秩序な数の元々のグループが規則的な構造となっている、ことがわかり、このツリーと上記2つのバイナリツリーの特性を満たすことができます!

しかし、同じ番号はどうなるのか、そのグループの上で、その後の昇順に自分自身を挿入し、[48,552,729,353,812]の順に挿入されている場合はどうなりますか?

昇順が挿入ので右ノードへのすべての時間が挿入されているので、新たに挿入されたデータは、この木の深刻な側枝につながる、すでに存在するノードのデータよりも常に大きいです!

図は、線形リストの中に、木の退化である最悪のシナリオは、とても自然に検索効率が低くされ、そしてそれの木の利点を活用しませんでした!

効率が大きく、バイナリツリー、バイナリツリー無側枝となるように再生する見つけるには、被験者はとてもバランスの取れたバイナリツリーで、バランスを維持しました!

バランスのバイナリツリー(AVL木)

平衡二分木は、特別な二分木であるので、彼二分木の二つの特性は、前述した満たす、ならびに特性:その左及びこれ以上1以下の右サブツリーの高さの差の絶対値は、左右のサブツリーこれは、バランスバイナリツリーです。

また、フロント[35274812293855]挿入が完了すると、図は、実際には、それがされているバランスの取れたバイナリツリーを見ました。

オーダーのバランスの取れたバイナリツリーに挿入[12,272,935,384,855]に従いあれば、何が起こるのだろうか?

私たちは、挿入とバランスの過程を見てみましょう。

このツリーは、常にバランスを維持するためにいくつかの特性のバランスの取れたバイナリツリーを満たすためにされています!私たちのツリーは、線形リストに退化しないように!

検索効率とバイナリ検索があまりにも同じであるように、我々は、回数が根に沿って見下ろすことができた見つける必要があります!

**バランスバイナリツリーは、ノードそれの数を収容することができますか?**これは、ツリーの高さをhとすると、各レイヤを受信したノードの最大数は2 ^(N-1)の関係を持つツリーの高さである、ツリー全体は、2 ^ 0 +まで収容するノード2 ^ 1 + 2 ^ 2 + ... + 2 ^(H-1)。

これに基づき、ツリーデータの高さは約20おそらく100W、データの100ワットから、最悪の場合には20回を見つける必要性をデータとの平衡二分木を見つけることです。

メモリ動作の場合は、効率が非常に高いです!しかし、我々のデータベース内のデータがディスク上に基本的に、バイナリツリーノードを読んで、それぞれが、我々は20倍、ディスクIOを通過するデータの一部を見つけその場合、ディスクIOのですか?

そのパフォーマンスが大きな問題となっています!ことを私たちは、それぞれの層は、複数のノードに対応することができますのでことを、この木を圧縮することはできませんか?私は短いですが、私は脂肪ああだが...

Bツリー

Zheke分厚いBツリーは、ツリーで、ミドルノートはそうツリー保存〜Bとして読んでいない、保存の細かいバーバーされていません

Bツリーはそれを持っていることを特徴とは何ですか?m次Bツリーは、次のような特徴を有しています。

  • m個のサブノードに各ノードのアップ。

  • ルート及びリーフノードに加えて、各ノードは、少なくともM / 2(切り上げ)サブノードを有しています。

  • 根は葉ノード、少なくとも二つのサブノードを含むルートノードではない場合。

  • すべてのリーフノードは、同じレベルにあります。

  • 各ノードは、M /2≤kk個の要素(キーワード)を含みます。

  • 昇順に各ノード要素(キーワード)。

  • (キー)ワード左ノードの各要素の値未満または要素(キーワード)に等しいです。右ノードの値は、要素(キーワード)以上です。

妻の母親が口を感じていないとの条件欄の束として、花嫁の価格にあなたを尋ね、それぞれが力あなたは非常に無知ようになります!

ここでは、一緒にすべての条件があり、あなたが理解する文字列に[6,7]配列に、たとえば3次Bツリーを挿入します!

だから、あなたはBツリーのいくつかの特徴がはっきりしているのですか?バイナリツリーでは、各ノードは唯一つの要素を有しています。

しかし、Bツリーは、各ノードは、複数の要素を含むことができ、要素内の非リーフノードは、左と右の子ノードへのポインタを有しています。

あなたは、プロセスがどのようにそれのようなものであるという要素を見つける必要がある場合は?私たちは、次のようなプロセスであることを、Bツリーで、次の24のキーワードを検索している場合我々は、図を参照してください。

私たちが見ることができるこのプロセスから、Bツリーのクエリ効率は平衡二分木よりも高くならないように思われます。しかし、パフォーマンスを向上させるはるかに短い時間のディスクIOを意味し、クエリがはるかに少ないです、それを通してノード数は、素晴らしいです。

前述の図から。Bツリー操作、我々は、参照素子2,3ができるような値に類似しています。

データのストアBツリーデータ構造にデータベース場合でも、データベース内のデータは、データがそれに保存されているか、データの部分ですか?

私たちは、次のチャートを見て:

共通ノードB-Treeが、要素の数は1です。しかし、上の図は、我々は、フォームのキー・データ部分の要素に分け、キーデータが特定のデータであり、主キーのデータです。

私たちは、あなたがルートに沿ってOK見下ろす番号を探している、効率が比較的高いです。

B +ツリー

B +ツリーは、Bツリーに基づいて最適化され、そしてそれは、より適切な外部ストレージ・インデックス構造を実現するために作ります。

B +などのBツリー構造ツリーが、いくつかの独自の特徴があります。

  • すべての非リーフノードは、キーワードのみの情報を格納します。

  • 全ての衛星データ(特定データ)リーフノードに存在します。

  • すべての葉ノードは、すべての要素に関する情報が含まれています。

  • これは、すべてのリーフノード間のポインタのチェーンを持っています。

上記Bツリー図は、B +ツリーになった場合、次のように、それがあるべきです。

我々は慎重に、図B-ツリーに比べて差があるものを見つけることができますか?

  • 非リーフノードでのみキー情報を持っており、上記第一の特徴点を満たします!

  • 私たちは、前述の第2の特徴点を満たすために、データ領域の下にあるすべてのリーフノードを持っています!

  • 非リーフノードは、ルート要素4,8のように、リーフノードで見つけることができるのデータは、上記第3の特徴点を満たすために、最も低いレベルのリーフ・ノードで見つけることができます!

  • 数字のリーフノード間の矢印は、午前四時の上記特性を満たすためにことに注意してください!

BツリーまたはB +ツリー?

同じディスク・ブロックで、基本単位として、ディスクブロック(ブロック)され、データベース内のこれら2つのデータ構造の選択の前に言えば、我々はまた、メモリにディスクからデータを読み取るためのオペレーティングシステムの知識を知っておく必要がありますデータではなく、それが何を取るために必要なものよりも、1回を読み出すことになります。

でも、1バイトしかならば、ディスクは、データの長さは順次メモリに読み戻す、この位置から開始されます。

データを使用する場合、その付近のデータも、多くの場合、すぐに使用すること。そのためには有名な産地原則のコンピュータ科学の理論に基づいています。

長さは、一般的に先読みされたページ(ページ)の整数倍です。コンピュータメモリ管理、ハードウェアおよびオペレーティング・システムの論理ページブロックは、しばしば、同じサイズの連続したブロックの主メモリ、ディスクストレージを分割され、各メモリブロックは、(多くのオペレーティングシステムでは、ページのサイズは、一般的に呼ばれます4K)。

BツリーとB +ツリーどのように選択するには?それの長所と短所は何ですか?

なぜなら、特定のデータのセーブ非リーフノードの①B-Treeが、そのリターンにキーワードを見つけるために時間を見つけます。

B +ツリーのリーフノードのすべてのデータは、各リーフノードに対して一度得られます。だから、BツリーとBツリーのB +ツリーの同じ高いレベルでのキーワードのためのより効率的な検索します。

②B +ツリーので、リーフノード内のすべてのデータは、ノード間に接続された以下のキーワードデータのキーワードより大きい見てポインタを、持っている、B +ツリーは、ちょうどキーを見つける必要がありますこのリストは、それに沿って横断して、Bツリーは、検索キーワードにルートノードを横断する必要があります。

③各ノードので(このノードは、データのページとして理解することができる)実際のデータ+ Bツリーの主キーを格納し、B +ツリーのリーフノードを格納する唯一の非キーワード情報を、各ページのサイズであります限定されるもので、Bツリーの同じページにはB +ツリー未満データ格納を格納することができるようになります。

ディスクI / O時間は、それによってクエリの効率に影響を与える場合従って同じ量のデータが、Bツリーの深さが大きくなり、クエリが増加します。

上記比較の観点においては、従来のリレーショナル・データベースであり、格納データ+にBツリーデータ構造を選択しています!

ここでは、他の同様のSQL Serverの原則のオラクルを説明するための例としてMySQL InnoDBストレージエンジンを持っています!

InnoDBストレージエンジンのデータ

InnoDBストレージエンジンでは、また、ページの概念があり、各ページには、デフォルトのサイズは4×4Kのサイズである16Kは、データが読み込まれるたびに読み込まれているさ!

私たちが今、ユーザーテーブルがあると、私たちが入った、書き込みデータ:

ここでもう一つ注意すべきは、現在のラインに通常バック、モバイルデータを削減するために、ページ内の新しい行を挿入しているか、宇宙に滞在する行を削除したので、特定のページ内のデータと完全に(ページの部分は後ろの詳細に入る)注文していません。

しかし、オーダーのデータにアクセスするために、各レコードに次のレコードへのポインタへのポインタを持っているため、一方向リンクリストを並べ替えられますが、ここで私が順に配置されたプレゼンテーションの便宜のために構成しています!

データがまだ比較的小さいので、あなただけのページを置くことができるので、rootのみ、主キー、およびデータもに格納されているルート(左数の具体的なデータの主キー、右の名前、性別表記を表します)。

我々はデータの後に10を書き込むと仮定し、Page1のは、完全な、そして新しいデータがそれを格納する方法でしょう書くのか?

私たちは、見た目に進みます。

「秦Shousheng「友人という男が来たが、データはすでにPage1のに適合していない、とページ分割の必要性について、この時間は、新しいページを生成しました。

InnoDB内のプロセスはどのようにそれのようなものでしょうか?

  • 新しいページ2を生成し、その後、ページ2へページ1の内容をコピーします。

  • 新しいページ3、ページ3への「秦Shousheng」のデータを生成します。

  • 元まだrootとしてのPage1、しかしインデックスのみを格納するデータが格納されていないページになった、と二つのサブノードのPage2、ページ3があります。

ある注意が必要な2つの問題があります。

①ページ2へなぜPage1のはとても少ないステップをコピーするコストのことを、ルートとして新しいページを作成するのではなく、コピー?

あなたがいる場合、ルートを再作成、および格納されているルートの物理アドレスが頻繁に見つけることが難しく、なるかもしれません。

メモリに先読みされるとInnoDBのルートノードでは、固定ノードの物理アドレスが良いだろう!

②上記特性Bの理解Bツリー+ツリーに基づいて、1ページ目、物品11は、核分裂時間データに挿入される10元のデータは、これがツリー11の少なくとも一つのため、分裂後の各ノードであること少なくとも11/2 = 5の要素点。

核分裂主キーがオリジナルで1-5ページまたはページでなければなりません後にそれはありませんでした、主キーデータ6-11は、ルートノードがプライマリキー6を保持し、新しいページに配置されますか?

これは場合、50%だけの新しいページスペースの利用率であり、より頻繁にページの分裂につながる場合。

したがって、この時点でInnoDBは元のページの任意のレコードを移動しないで、新たに作成されたページに、新しいデータを最適化されています。

以下のようにデータの書き込みと、木は徐々に頭角を現します:

たびに新しいデータが書き込み続け満たさページで、その後、新しいページを作成し、実際には、そこに隠された状態であり、それは主キーの増分です!

主キーは、新たに挿入された書き込みデータは元のページ、高い挿入効率には影響しませんインクリメント!そして、高いページの利用!

主キーが無秩序またはランダム、および挿入のそれぞれは、元のページの頻繁な分裂につながることである場合は、挿入の効率に影響を与えます!ページの利用を削減!これも理由であるInnoDBテーブルの主キー増分の推奨設定!

非リーフノードに格納されているこの木は、もしテーブルが主キーが起こらなかったことが主キー、ありますか?テーブルには主キーがない場合はInnoDBでは、あなたは主キーとして目に見えないフィールドを生成しますが存在しない場合、デフォルトは、コラムの一意のインデックスを構築していることがわかります!

データページにつながるユーザテーブル頻繁に挿入および欠失は、スペース・ページの断片化、低利用率となって、だけでなく、ツリー内の結果が「High」になり、クエリの効率を低下させた場合、削除データ挿入に存在しています!これは、インデックスを再構築することによって、クエリのパフォーマンスを向上させる破片を排除することができます!

InnoDBのデータ検索エンジン

どのようにデータを見つけるには?

  • **データが存在するページを見つけます。**それだけでB +ツリーの検索処理の前にしています。この検索処理は、リーフノードまで見て開始すること根から、同じです。

  • **ページ内の特定のデータを探します。メモリへのステップ1 **リーフノードデータから読み出し、その後、ブロック探索の方法で特定のデータを見つけます。

私たちは、漢字と新華辞書と同じであることがわかり、ピンイン辞書指数によると、その後は、特定の文字を見つけるために、ページを指定するページへの最初のナビゲート。

InnoDBの後はすぐにそれにマスターキーを見つけるためにどの戦略でページを検索しますか?私たちは、ページの構造を理解し始める必要があること。

左ページディレクトリの青色領域と呼ばれる、スロットの複数からなるこの領域は、それが疎インデックス構造、すなわちされ、溝は4つのレコードの少なくとも一部が、レコードは8までに属し、複数のレコードに属していてもよいです。

データ貯蔵タンクは、私たちはあなたを介してスロットにおおよその場所を見つけることができる二分法最初のデータを検索する際に、発注されます。

データ領域の右側の領域は、各データ・ページは、データの複数の行が含まれています。トップでの図と二つの特別なInfimumとSupremumの一番下の行は、これら2つの仮想列であることに注意してください。

次のレコードを指し示すポインタInfimum Supremumにおける他のユーザデータが存在しないことです。

ユーザデータは、Infimum内の次のレコードへのポインタが、このページを、現在の最小のユーザレコードのページに向け最大加入者レコードの次のレコードへのポインタ場合、ポイントSupremumは、全ページ内のすべての行を指す単一の形成リストへ。

ページディレクトリの行は、ブロックが順序付けされる間、すなわち、「4」は、最大データブロック列に向かう主キー溝は、より良好な「8」溝よりもある、複数の論理ブロックに分割されデータ・ブロック・ポイント内の最小主キーの行が小さくなっています。しかし、ブロック内の行が順番に限りません。

領域(図中のピンク色の領域)n_owned各レコードの行、n_owned識別するデータブロックの数を有しています。

偽の値を記録する1常にInfimumをn_owned、Supremumの記録範囲をn_owned [1,8]であり、他のユーザーが[4,8]の記録範囲をn_owned。

各ブロックと、他のユーザに価値を有するであろうn_owned記録のみ最大片0 n_owned記録されています。

だから我々は、このスロットに「8」でページディレクトリである主キーレコード6、最初の二分法により、スパースインデックスに対応するスロットを見つけ、探しているとき。

データブロックにスロットポイントの「8」が最大に記録され、単独でリンクされたリストデータ構造である、それは逆引きではありません。

したがって、「4」溝であるグルーブを見つけ、その後、記録ポインタ「4」で鎖に沿って標的配列に検索する必要が最大のユーザレコード溝です。

&非クラスタ化インデックスクラスタ化インデックス

保存されたデータの前にクラスタ化インデックスが実証されて実現し、「ユーザ名」は、非クラスタ化インデックスを確立するために、上記のユーザー表が必要な場合は、それを達成する方法ですか?

私たちは見て:

ストレージ構造は、以前に非クラスタ化インデックスは、リーフノードのデータが格納された特定のデータの一部ではなくなったが、データはインデックスキーをクラスタ化されたことを除いて、同じです。

だから、非クラスタ化インデックス・ルックアップのプロセスを通じて、その後のは、対応するデータを見つけるために、主キーインデックスツリーにキーインデックスを収集してみましょう、キーが対応するインデックスキーのインデックスをクラスタ化された見つけることです、このプロセスはバックテーブルに呼ばれています!

PS:これらの名前の数字はネットワークから、この記事を読んharming'reのない希望はありませんが、あなた〜^ _ ^

InnoDBテーブルとMyISAMのエンジンの比較

それに異なる何ので、保存と検索例えば、InnoDBエンジンを取っている、というのMyISAMとInnoDBのストレージを含む上記、?ホールドバックワードは、図を縮小します:

主キーのインデックスのピクチャーMyISAMストレージ構造は、我々は異なるが見ることができます:

  • リーフノードのデータ領域は、実際のデータを格納するための主キーインデックスツリーではありません、データレコードアドレスに格納されます。

  • 主キーのストレージを注文データに格納されていない、書かれた順番に位置しています。

データが物理的に挿入するためにのMyISAMエンジンによって記憶されている間、そのInnoDBエンジンデータは、物理的に、主キーシーケンスを格納されています。

そして、のMyISAMリーフ・ノードは、データ、ストレージ構造と非クラスタ化インデックスクラスタ化インデックスが似ているデータを検索するために、非クラスタ化インデックスを使用してバックテーブルに必要がない場合、あなたは直接、非クラスタ化インデックスツリーでのデータのアドレスを見つけることができますが格納されていませんこの検索は、InnoDBの効率よりも高くなります!

インデックスの最適化のヒント

あなたは、多くの場合、例えば、多くの記事や書籍で推奨インデックスの一部の使用を見ることができます:

  • あいまいクエリは%で始まるように、インデックスが失敗につながります。

  • ない以上5以下とインデックスのテーブルを作成します。

  • カバーインデックスを使用してみてください。

  • データを複製し、複数の列にないビルドインデックスに試してみてください。

  • ......

ここで多くは、それらを表示されません!この記事を読んで、私たちはこれらの推奨事項を持っている理由を分析質問に行くことができますか?

なぜファジー%のようなクエリで始まり、インデックスが故障につながるのだろうか?なぜ5以下ではないとインデックスのテーブルを構築しますか?

なぜ?なぜ?なぜ?私はあなたがここで見ると自分の思考の一部は、右の答えを持っていなければならないと考えていますか?

おすすめ

転載: juejin.im/post/5df09dd0f265da33ce4567fb