【図解】B+木(B+ Tree)の探索・クエリ処理をわかりやすく解説
B+木の探索(クエリ)とは
本記事では、B+木(B+ Tree)における要素の検索方法について詳しく解説します。B+木の探索は「B+木クエリ」とも呼ばれ、基本的な流れはB木(B-Tree)のクエリ処理と非常によく似ています。ただし、B+木にはB木にはない重要な特徴があり、それは範囲クエリ(レンジクエリ)をサポートしている点です。
まず、次のようなB+木を例として考えてみましょう。
B+木の例:

単一キーの検索手順
B+木の探索は、二分探索木の考え方に近いものです。上記の木から「63」を検索するケースを例に、手順を説明します。
- 探索は根(ルート)ノードから開始します。「63」はルートの要素「60」より大きく「75」より小さいため、「60」の右側の子ノードへ移動します。
- 右側の子ノードにも「63」が存在しますが、ここがB木との大きな違いです。このノードは内部ノードであり、実際のデータは格納されていません(B木であれば、この時点で検索が完了します)。
- さらに下位へ進み、葉(リーフ)レベルに到達して初めて「63」というレコードが見つかります。これが実際の検索結果となります。
範囲クエリをサポートする理由
たとえば「63から78までのすべての要素」を取得したい場合を考えてみましょう。B+木では、各要素ごとに探索をやり直す必要はありません。まず最初の値(63)が属する葉ノードを特定し、その後は葉ノード同士が連結リストのようにつながっているという構造を利用して、78に達するまで順番にノードをたどるだけで済みます。
この仕組みにより、B+木は大量データの中から特定の範囲のデータを非常に効率的に取り出せるため、データベースのインデックスなどで広く採用されています。
探索アルゴリズム
続いて、B+木内の要素を検索するアルゴリズムを確認しましょう。
BPlusTreeSearch(root, key):
- 入力: 木の根ノードと、検索対象のキー
- 出力: キーを持つノードの値。存在しない場合は null を返す
現在のノードのレコードに対して二分探索を実行する
'key' を持つレコードが見つかった場合:
該当するレコードを返す
そうでなく、現在のノードが葉ノードでありキーが見つからない場合:
null を返す
-
データ構造の範囲ツリー(レンジツリー)とは?仕組み・kd-treeとの違い・構築方法を解説
範囲ツリー(range tree)は、点の集合を格納するための順序付き木構造として定義されるデータ構造です。最大の特徴は、指定された範囲内に存在するすべての点を効率的に取得できる点にあり、実務では主に2次元以上の空間で実装されます。範囲ツリーはkd-tree(kd木)とよく似た構造を持っていますが、両者には明確なトレードオフがあります。範囲ツリーはクエリ時間が O(logd n + k) とkd-treeより高速である一方、必要な記憶領域は O(n logd-1 n) と大きくなります。ここで、d は空間の次元数、n は木に格納されている点の総数、k は1回のクエリで取得される点の数を表します
-
データ構造:仮想木におけるスプレー操作のアルゴリズム
仮想木(Virtual Tree)では、一部の辺は実線(solid)として扱われ、その他の辺は破線(dashed)として扱われます。通常のスプレー操作は、実線で構成される木(solid tree)の内部でのみ実行されます。仮想木内のノード y でスプレーを行うには、以下に示す手法が用いられます。 このアルゴリズムは、木を3回走査し(各パスで1回ずつ)、その都度木を書き換えていきます。第1パスでは、ノード y から開始して実線の木内でのみスプレーを行うことで、y から木全体の根までの経路が破線に変わります。続いて、スプライシング(splicing)によってこの経路を実線に変換します。最後にノード