(57)【要約】データベース管理装置は、インデックスエントリとリードカウンタ及びライトカウンタを含むアクセスカウンタとをそれぞれ有する複数のインデックスブロックと、インデックスブロックへのリードアクセスに応じてリードカウンタを更新し、インデックスブロックへの更新アクセスに応じてライトカウンタを更新するアクセス管理手段と、新たなインデックスエントリの挿入対象のリーフブロックにおけるリードカウンタとライトカウンタとの比較結果に基づいて、新たなインデックスエントリの格納先として、他のインデックスブロックのインデックスエントリにより特定されない拡張ブロックを取得し、当該拡張ブロックを特定するための特定情報を挿入対象のリーフブロックに設定する拡張ブロック操作手段と、を備える。
2012114402.tif 000002
【特許請求の範囲】
【請求項１】
表データを格納するデータブロックを含むデータベースを管理するデータベース管理装置において、
前記表データを構成する１つの行データ又は他のインデックスブロックを特定するための少なくとも１つのインデックスエントリと、リードカウンタ及びライトカウンタを含むアクセスカウンタとをそれぞれ有し、ツリー構造を持つ複数のインデックスブロックと、
前記表データに対するデータ操作に応じて前記ツリー構造に沿ってアクセスされたインデックスブロックに関し、インデックスブロックへのリードアクセスに応じてリードカウンタを更新し、インデックスブロックへの更新アクセスに応じてライトカウンタを更新するアクセス管理手段と、
前記データブロックに挿入される新たな行データを特定するための新たなインデックスエントリを前記複数のインデックスブロックのうちの挿入対象のリーフブロックに挿入するデータ挿入手段と、
前記挿入対象のリーフブロックにおける前記リードカウンタと前記ライトカウンタとの比較結果に基づいて、前記新たなインデックスエントリの格納先として、他のインデックスブロックのインデックスエントリにより特定されない拡張ブロックを取得し、当該拡張ブロックを特定するための特定情報を前記挿入対象のリーフブロックに設定する拡張ブロック操作手段と、
を備えることを特徴とするデータベース管理装置。
【請求項２】
前記拡張ブロック操作手段は、前記挿入対象のリーフブロックにおける前記ライトカウンタと前記リードカウンタとの比較結果に基づいて、前記拡張ブロックを他のインデックスブロックのインデックスエントリにより特定されるリーフブロックとなるように設定することを特徴とする請求項１に記載のデータベース管理装置。
【請求項３】
前記拡張ブロック操作手段は、前記リードカウンタ及び前記ライトカウンタに基づいて、前記挿入対象のリーフブロックにおける全アクセスに対するライトアクセスの比率が所定閾値を超えるか否かを判定し、前記ライトアクセスの比率が所定閾値を超える場合に、他のインデックスブロックのインデックスエントリにより特定されない拡張ブロックを取得する、
ことを特徴とする請求項１又は２に記載のデータベース管理装置。
【請求項４】
前記拡張ブロック操作手段は、前記リードカウンタ及び前記ライトカウンタに基づいて、前記挿入対象のリーフブロックにおける全アクセスに対するリードアクセスの比率が所定閾値を超えるか否かを判定し、前記リードアクセスの比率が所定閾値を超える場合に、前記拡張ブロックを他のインデックスブロックのインデックスエントリにより特定されるリーフブロックとなるように設定する、
ことを特徴とする請求項２又は３に記載のデータベース管理装置。
【請求項５】
前記アクセス管理手段は、前記拡張ブロックに格納されたインデックスエントリに対してアクセスされた場合には、当該拡張ブロックを特定するための特定情報が設定されたリーフブロックのアクセスカウンタを更新する、
ことを特徴とする請求項１から４のいずれか１項に記載のデータベース管理装置。
【請求項６】
表データを格納するデータブロックを含むデータベースを管理するプログラムにおいて、
コンピュータに、
前記表データを構成する１つの行データ又は他のインデックスブロックを特定するための少なくとも１つのインデックスエントリと、リードカウンタ及びライトカウンタを含むアクセスカウンタとをそれぞれ有し、ツリー構造を持つ複数のインデックスブロックと、
前記表データに対するデータ操作に応じて前記ツリー構造に沿ってアクセスされたインデックスブロックに関し、インデックスブロックへのリードアクセスに応じてリードカウンタを更新し、インデックスブロックへの更新アクセスに応じてライトカウンタを更新するアクセス管理手段と、
前記データブロックに挿入される新たな行データを特定するための新たなインデックスエントリを前記複数のインデックスブロックのうちの挿入対象のリーフブロックに挿入するデータ挿入手段と、
前記挿入対象のリーフブロックにおける前記リードカウンタと前記ライトカウンタとの比較結果に基づいて、前記新たなインデックスエントリの格納先として、他のインデックスブロックのインデックスエントリにより特定されない拡張ブロックを取得し、当該拡張ブロックを特定するための特定情報を前記挿入対象のリーフブロックに設定する拡張ブロック操作手段と、
を実現させることを特徴とするプログラム。
【請求項７】
前記拡張ブロック操作手段は、前記挿入対象のリーフブロックにおける前記ライトカウンタと前記リードカウンタとの比較結果に基づいて、前記拡張ブロックを他のインデックスブロックのインデックスエントリにより特定されるリーフブロックとなるように設定することを特徴とする請求項６に記載のプログラム。
【請求項８】
表データを格納するデータブロックを含むデータベースを管理するデータベース管理方法において、
前記表データを構成する１つの行データ又は他のインデックスブロックを特定するための少なくとも１つのインデックスエントリと、リードカウンタ及びライトカウンタを含むアクセスカウンタとをそれぞれ有し、ツリー構造を持つ複数のインデックスブロックを格納するコンピュータが、
前記表データに対するデータ操作に応じて前記ツリー構造に沿ってアクセスされたインデックスブロックに関し、インデックスブロックへのリードアクセスに応じてリードカウンタを更新し、インデックスブロックへの更新アクセスに応じてライトカウンタを更新し、
前記データブロックに挿入される新たな行データを特定するための新たなインデックスエントリを前記複数のインデックスブロックのうちの挿入対象のリーフブロックに挿入し、
前記挿入対象のリーフブロックにおける前記リードカウンタと前記ライトカウンタとの比較結果に基づいて、前記新たなインデックスエントリの格納先として、他のインデックスブロックのインデックスエントリにより特定されない拡張ブロックを取得し、
前記拡張ブロックを特定するための特定情報を前記挿入対象のリーフブロックに設定する、
ことを特徴とするデータベース管理方法。
【請求項９】
前記コンピュータが、更に、
前記挿入対象のリーフブロックにおける前記ライトカウンタと前記リードカウンタとの比較結果に基づいて、前記拡張ブロックを他のインデックスブロックのインデックスエントリにより特定されるリーフブロックとなるように設定する、
ことを特徴とする請求項８に記載のデータベース管理方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ツリー構造のインデックスが付加されたデータベースの管理技術に関する。
【背景技術】
【０００２】
大量のデータから少量のデータを高速に検索するために、データにインデックスを付与するのが一般的である。検索処理が多く実行されるのはデータベースであり、最も広く用いられているデータベースの一つは、表形式でデータを管理する関係データベースである。表は、行と列を持ち、例えば、一つの行に一つの取引に関するデータを格納する。行は、複数の列から構成され、例えば、ある列に日付データを、別の列に売上金額を格納する。【０００３】
この場合、特定の日付における総売上金額を得る方法には、フルスキャン、インデックススキャン等がある。フルスキャンでは、全ての行に関して日付が一致するかどうかを調べ、一致する行の売上高を加算する。インデックススキャンでは、日付が一致する行をインデックスによって特定し、特定された行から売上高の総和を得る。インデックススキャンは、全行数に比べて日付が一致する行の数が十分に小さいときに効率的である。【０００４】
Ｂツリーは、インデックスを格納するデータ構造の一つとして知られている。例えば、非特許文献１には、Ｂツリーを使った検索、Ｂツリーへのデータの挿入、Ｂツリーへのデータの削除の各アルゴリズムが記載されている。非特許文献２には、広く用いられている関係データベースのＯＲＡＣＬＥ（登録商標）におけるＢツリーの説明が記載されている。【０００５】
このようなＢツリーインデックスを用いることにより、行数をｎとすると、「ｌｏｇ  ｎ」に比例する計算量でデータを検索することができる。なお、フルスキャンの計算量は、ｎに比例する。【０００６】
また、特許文献１には、同一のキー値に対して複数のアクセスが生じた場合に発生するロック競合を減らすために、複数のツリー構造のインデックスを用意し、キー値をいずれか１つに格納するインデックス管理方式が提案されている。この方式では、インデックス中のキー数が均等化され、各インデックスに対するアクセス数がカウントされることで、各インデックスのアクセス負荷の均等化が図られる。【０００７】
特許文献２には、Ｂツリーインデックスでのロック競合の回数を数え、多数のロック競合が起きた場合に、Ｂツリーを分割するデータベース管理手法が提案されている。【０００８】
特許文献３には、Ｂツリー等のバランス木にレコード追加する場合に、ブロックを分割することなく、１回の入出力処理で読み書きできる大きさまでそのブロックを拡大させるレコード追加処理方式が提案されている。なお、この方式では、限界の大きさまでブロックが拡大された後は、ブロック分割が行われる。【０００９】
特許文献４には、ノンデンスＢツリークラスタ構造を用いた格納構造によりデータを管理するデータ処理システムにおけるスプリット制御方法が提案されている。この方法では、オーバーフロー時のブロック分割を即時に行うのではなく、対象レコードをオーバーフロー領域へ書き込むことで、ブロック分割処理のオーバーヘッドが低減される。【００１０】
また、非特許文献３には、挿入アプリケーションでの索引のホットスポットを除去するように設計されている逆キー索引手法が提案されている。例えば、データ挿入時の時刻を示す列にＢツリーインデックスを張った場合には、インデックスの一番右の（一番大きい値を持つ）リーフブロックとその上位のブランチブロックにライトアクセスが集中する。逆キー索引手法は、このようなｒｉｇｈｔ−ｇｒｏｗｉｎｇ  ｉｎｄｅｘと呼ばれる状況を避けるため、インデックスのキー値を反対にして構築する。具体的には、通常の索引では、一般的には、キー値（１０２）及びキー値（１０３）は、同じブロックに挿入されるが、逆キー索引では、これらのキー値が、反対にされた値（２０１）及び値（３０１）として扱われることにより、異なるブロックに挿入される。
【先行技術文献】
【特許文献】
【００１１】
【特許文献１】特開平５−３３４１５３号公報
【特許文献２】特開平７−２００３７６号公報
【特許文献３】特許第２６１５０４６号
【特許文献４】特許第２７０８６５７号
【非特許文献】
【００１２】
【非特許文献１】Comer, D. "Ubiquitous B-Tree", ACM Computing Surveys, vol.11, no.2, p.121-137, June 1979
【非特許文献２】"Oracle Database概要"、10g リリース2、部品番号：B19215-02、2006年3月（図5-7）、http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19215-02.pdf
【非特許文献３】"Oracle Database パフォーマンス・チューニング・ガイド"、10g リリース2 (10.2)、部品番号：B19207-02、2008年5月、2-12（アプリケーション設計の原則）、http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19207-02.pdf
【発明の概要】
【００１３】
Ｂツリーインデックスが付加されたデータベースでは、一般的には、検索は高速であるが、データの挿入及び削除は低速になる。Ｂツリーインデックスが付加されていないデータベースに対するデータの挿入及び削除は、単に表として記録されたデータを操作すればよい。しかしながら、Ｂツリーインデックスが付加された表に対するデータの挿入及び削除は、Ｂツリーに記録されたデータも操作しなければならないからである。更に、Ｂツリーでは、操作を加えるブロックの空き領域の過不足によって、ブロック自体の追加及び削除が発生する場合もある。この場合、そのブロックの上位のブロックのデータも操作する必要がある。
【００１４】
従って、データベースにインデックスを付加する形態、及び、データベースにインデックスを付加しない形態は、共に、メリット及びデメリットを持つため、データベースに対する処理全体を考慮した場合、いずれの形態も十分な性能を達成できない可能性がある。このような問題は、例えば、特定の範囲のキーの挿入及び検索が頻繁に発生する場合等に生じ得る。これは、特定の範囲のキーが頻繁に挿入される場合には、対応するブロックにライトアクセスが集中し、特定の範囲のキーが頻繁に検索される場合には、対応するブロックにリードアクセスが集中するからである。
【００１５】
上述のような問題は、リーフブロック又はブランチブロックには近い値を持つキーが格納されることにも起因する。そこで、上述の逆キー索引によれば、特定範囲のキーの挿入処理及び検索処理の対象となるブロックを分散させることができるため、上述のような問題の一部を解決することができる。
【００１６】
ところが、逆キー索引には、範囲検索ができないという問題がある。また、データベースの管理者や運用者が、逆キー索引を用いるか否かの決定のために、検索及び挿入の発生頻度を正確に認識する必要があるという問題がある。
【００１７】
本発明の目的は、ツリー構造のインデックスが付加されたデータベースの性能を最適化するためのデータベース管理技術を提供することにある。
【００１８】
本発明の各態様では、上述した課題を解決するために、それぞれ以下の構成を採用する。
【００１９】
第１の態様は、表データを格納するデータブロックを含むデータベースを管理するデータベース管理装置に関する。第１態様に係るデータベース管理装置は、上記表データを構成する１つの行データ又は他のインデックスブロックを特定するための少なくとも１つのインデックスエントリと、リードカウンタ及びライトカウンタを含むアクセスカウンタとをそれぞれ有し、ツリー構造を持つ複数のインデックスブロックと、上記表データに対するデータ操作に応じてツリー構造に沿ってアクセスされたインデックスブロックに関し、インデックスブロックへのリードアクセスに応じてリードカウンタを更新し、インデックスブロックへの更新アクセスに応じてライトカウンタを更新するアクセス管理手段と、データブロックに挿入される新たな行データを特定するための新たなインデックスエントリを複数のインデックスブロックのうちの挿入対象のリーフブロックに挿入するデータ挿入手段と、挿入対象のリーフブロックにおけるリードカウンタとライトカウンタとの比較結果に基づいて、上記新たなインデックスエントリの格納先として、他のインデックスブロックのインデックスエントリにより特定されない拡張ブロックを取得し、当該拡張ブロックを特定するための特定情報を挿入対象のリーフブロックに設定する拡張ブロック操作手段と、を備える。
【００２０】
第２の態様は、表データを格納するデータブロックを含むデータベースを管理するデータベース管理方法に関する。第２態様に係るデータベース管理方法では、表データを構成する１つの行データ又は他のインデックスブロックを特定するための少なくとも１つのインデックスエントリと、リードカウンタ及びライトカウンタを含むアクセスカウンタとをそれぞれ有し、ツリー構造を持つ複数のインデックスブロックを格納するコンピュータが、上記表データに対するデータ操作に応じてツリー構造に沿ってアクセスされたインデックスブロックに関し、インデックスブロックへのリードアクセスに応じてリードカウンタを更新し、インデックスブロックへの更新アクセスに応じてライトカウンタを更新し、データブロックに挿入される新たな行データを特定するための新たなインデックスエントリを複数のインデックスブロックのうちの挿入対象のリーフブロックに挿入し、挿入対象のリーフブロックにおけるリードカウンタとライトカウンタとの比較結果に基づいて、上記新たなインデックスエントリの格納先として、他のインデックスブロックのインデックスエントリにより特定されない拡張ブロックを取得し、当該拡張ブロックを特定するための特定情報を前記挿入対象のリーフブロックに設定する。
【００２１】
本発明の他の態様としては、上記第１態様に係る各構成をコンピュータに実現させるプログラムであってもよいし、このプログラムを記録したコンピュータが読み取り可能な記録媒体であってもよい。この記録媒体は、非一時的な有形の媒体を含む。
【００２２】
上記各態様によれば、ツリー構造のインデックスが付加されたデータベースの性能を最適化するためのデータベース管理技術を提供することができる。
【図面の簡単な説明】
【００２３】
【図１】図１は、第１実施形態におけるデータベース（ＤＢ）システムの構成例を示す概念図である。
【図２】図２は、ブランチブロックの構成例を概念的に示す図である。
【図３】図３は、リーフブロックの構成例を概念的に示す図である。
【図４】図４は、第１実施形態におけるデータベース（ＤＢ）システムのデータ検索時の動作例を示すフローチャートである。
【図５】図５は、ブランチブロック、リーフブロック及びデータブロックの関係の例を概念的に示す図である。
【図６】図６は、第１実施形態におけるデータベース（ＤＢ）システムのデータ挿入時の動作例を示すフローチャートである。
【図７】図７は、第１実施形態におけるデータベース（ＤＢ）システムのデータ削除時の動作例を示すフローチャートである。
【図８】図８は、第２実施形態におけるデータベース（ＤＢ）システムの動作例を示すフローチャートである。
【発明を実施するための形態】
【００２４】
以下、本発明の実施の形態としてのデータベースシステム（以降、ＤＢシステムと表記する）について説明する。なお、以下に挙げる各実施形態はそれぞれ例示であり、本発明は以下の各実施形態の構成に限定されない。
【００２５】
［第１実施形態］
〔システム構成〕
図１は、第１実施形態におけるＤＢシステム１０の構成例を示す概念図である。ＤＢシステム１０は、図１に示すように、ハードウェア構成として、ＣＰＵ１、メモリ２（ＲＡＭ（Random Access Memory）、ＲＯＭ（Read Only Memory）、ハードディスク（ＨＤＤ）等）、入出力インタフェース３等を有する。これら各ハードウェア要素は例えばバス５により接続される。入出力インタフェース（入出力Ｉ／Ｆ）３は、外部のコンピュータ等と通信を行うためのネットワークインタフェースやユーザインタフェース等を含む。
【００２６】
ＤＢシステム１０は、例えば、メモリ２に格納されるプログラムがＣＰＵ１により読み出され実行されることにより、以下のような各処理部を実現する。ＤＢシステム１０は、データベース管理部（以降、ＤＢ管理部と表記する）１００、データベース（以降、ＤＢと表記する）部２００等を有する。
【００２７】
なお、図１の例では、ＤＢシステム１０が１台のコンピュータとして実現される例を示すが、複数のコンピュータで実現されてもよい。また、図１の例では、１つのＣＰＵ１のみが示されるが、複数のプロセッサ（例えば、ＣＰＵ、ＤＳＰ（Digital Signal Processor）等）を有していてもよい。例えば、ＤＢ管理部１００とＤＢ部２００とが異なるコンピュータ又はＣＰＵ上で実現されてもよい。本実施形態は、ＤＢシステム１０のハードウェア構成を限定しない。
【００２８】
ＤＢ部２００は、メモリ２上に実現され、複数のブロック２１０（図１では２１０（＃１）、２１０（＃２）、２１０（＃ｎ）として表記）を含む。各ブロック２１０は、例えば、所定容量（例えば、４キロバイト（ＫＢ））の連続した記憶領域として確保される。ブロック２１０間は、連続領域として確保されてもよいし、非連続な各領域として確保されてもよい。本実施形態は、ブロック２１０の領域サイズを限定しない。
【００２９】
各ブロック２１０は、インデックスを格納するブロック（以降、インデックスブロックとも表記される）と、データを格納するブロック（以降、データブロックとも表記される）２４０とに大別される。データブロック２４０は、任意の表（テーブル）を格納する。
【００３０】
インデックスブロックは、ツリー構造（例えば、Ｂツリー（Balanced Tree）構造）を持ち、更に、ブランチブロック２２０と、リーフブロック２３０とに大別される。ブランチブロック２２０及びリーフブロック２３０の各々は、インデックスとなる少なくとも１つのエントリを格納する。各インデックスブロックに格納されるエントリは、インデックスエントリと呼ぶこともできる。インデックスエントリは、検索対象となるキー値と識別子（ＩＤ）とを含む。
【００３１】
リーフブロック２３０は、インデックスブロックの中の最下層のブロックである。リーフブロックのエントリに含まれる識別子は、データブロックのいずれか１つの行データを特定するためのデータである。その識別子は、例えば、特定すべき行データの先頭を指すポインタとその行データのサイズとから構成される。
【００３２】
ブランチブロック２２０は、リーフブロック２３０又は他のブランチブロック２２０へのリンクを持つブロックである。このリンクは、インデックスエントリの識別子によって実現される。即ち、ブランチブロック２２０のエントリに含まれる識別子は、いずれか１つのブランチブロック２２０又はいずれか１つのリーフブロック２３０を特定するポインタである。以降、最上位のブランチブロック２２０をルートブロックと表記する場合もある。ここで、最上位とは、検索時に最初に検索されることを意味する。
【００３３】
以降、インデックスエントリの識別子によりリンクされた各インデックスブロックにおいて、そのインデックスエントリを含むブランチブロック２２０を親ブロックと表記し、そのインデックスエントリの識別子で特定されるリーフブロック２３０又は他のブランチブロック２２０を子ブロックと表記する場合もある。
【００３４】
図２は、ブランチブロック２２０の構成例を概念的に示す図である。図２に示すように、ブランチブロック２２０は、ブロックヘッダと少なくとも１つのインデックスエントリとをそれぞれ含む。インデックスエントリは、上述したように、キー値（図２の「ｋｅｙ」）と識別子（図２の「ｉｄ」）とを含む。ブロックヘッダには、ブロック種、アクセスカウンタ等が設定される。   
【００３５】
ブロック種は、リーフブロック、ブランチブロック等を識別するための情報である。アクセスカウンタは、リードカウンタ及びライトカウンタを含み、インデックスブロックへのアクセスの数をカウントする。具体的には、ブランチブロック２２０へのリードアクセスに応じてリードカウンタが更新され、ブランチブロック２２０への更新アクセス（エントリ追加及びエントリ削除）に応じてライトカウンタが更新される。
【００３６】
図３は、リーフブロック２３０の構成例を概念的に示す図である。図３に示すように、リーフブロック２３０は、そのブロックヘッダに拡張ポインタを有する点において、ブランチブロック２２０と異なる。リーフブロック２３０のその他の構成については、ブランチブロック２２０と同様である。拡張ポインタは、リーフブロック２３０の容量を拡張するために追加される拡張ブロックを特定するための情報である。例えば、拡張ポインタには、拡張ブロックのアドレスが設定される。なお、拡張ブロックを持たないリーフブロック２３０の拡張ポインタには、無効値（例えば、ＮＵＬＬ）が設定される。以降、リーフブロック２３０を拡張するとの表記は、そのリーフブロック２３０に拡張ブロックを付加することを意味する。
【００３７】
拡張ブロックは、メモリ２上に実現される、上述のブロック２１０のうちの一つである。拡張ブロックには、リーフブロック２３０と同様に、データブロックのいずれか１つの行データを特定する識別子を含むインデックスエントリが格納される。拡張ブロックは、他のインデックスブロック（ブランチブロック２２０）のインデックスエントリにより特定されない点において、インデックスブロックとは異なる。１つのリーフブロック２３０に対して複数の拡張ブロックが追加された場合には、拡張ブロックには、他の拡張ブロックを特定するための拡張ポインタが設定される。
【００３８】
上述のように、図２及び図３では、インデックスブロック内の連続領域に、ブロックヘッダ内の各値及び各エントリが格納される例を示したが、ブロックヘッダ内の各値と各エントリとは、相互に関連付けられていれば、必ずしも連続した領域に格納されなくともよい。
【００３９】
以降、ブランチブロック２２０、リーフブロック２３０、データブロック２４０、及び拡張ブロックを単にブロックと表記する場合もある。また、インデックスエントリを単にエントリと表記する場合もある。
【００４０】
ＤＢ管理部１００は、アクセス管理部１１０、検索部１２０、データ挿入部１３０、データ削除部１４０、拡張ブロック操作部１５０等を含む。ＤＢ管理部１００に含まれるこれら各処理部も、メモリ２に格納されるプログラムがＣＰＵ１により読み出され実行されることにより、ソフトウェア要素として実現される。
【００４１】
検索部１２０は、検索キーを取得し、この検索キーに対応する列（フィールド）のデータを含む行をデータブロック２４０から抽出する。検索キーは、他の装置から通信を介して取得されてもよいし、ＣＰＵ１により実行されているプロセス等のような他の処理部から取得されてもよいし、ユーザインタフェースを介してユーザにより入力されてもよい。
【００４２】
検索部１２０は、データブロック２４０における抽出すべき行を特定するために、インデックス検索を行う。このインデックス検索において、検索部１２０は、まず、ルートブロックにアクセスする。検索部１２０は、ルートブロックに含まれるエントリのうち、検索キー以下の最大のキー値を持つエントリ、又は、検索キー以上の最小のキー値を持つエントリを検索する。
【００４３】
検索部１２０は、抽出されたエントリの識別子により特定される他のブランチブロック２２０又はリーフブロック２３０を読み出す。検索部１２０は、他のブランチブロック２２０が読み出された場合には、上記のルートブロックに対する検索と同様に特定のエントリを抽出する。一方、検索部１２０は、リーフブロック２３０が読み出された場合には、検索キーの条件を満たすエントリを抽出し、そのエントリの識別子で特定される行データをデータブロック２４０から抽出する。
【００４４】
検索部１２０は、リーフブロック２３０が読み出された場合で、かつ、そのリーフブロック２３０の拡張ポインタに有効値が設定されている（そのリーフブロック２３０が拡張されている）場合には、リーフブロック２３０に含まれるエントリと、その拡張ポインタで特定される拡張ブロックに含まれるエントリとを対象に、検索キーの条件を満たすエントリを抽出する。言い換えれば、検索部１２０は、拡張ブロックをリーフブロック２３０のインデックスエントリを格納する領域の一部として扱う。
【００４５】
データ挿入部１３０は、挿入する行データを受け取り、データブロック２４０にその行データを書き込む。このとき、データ挿入部１３０は、その挿入された行データに基づいて、インデックスブロック内のインデックスを更新する。データブロック２４０への書き込みは、例えば、挿入すべき行データよりも大きな空き領域を持つブロックのいずれか１つに書き込まれる。
【００４６】
データ挿入部１３０は、インデックスの更新において、対応するリーフブロック２３０に、その挿入された行データに対応する新たなインデックスエントリを追加する。この新たなインデックスエントリは、キーが設定される列であって挿入された行に含まれる列のデータをキー値として含み、更に、その行を特定するための識別子を含む。
【００４７】
データ挿入部１３０は、更新対象のリーフブロック２３０が拡張されている場合には、そのリーフブロック２３０の拡張ブロックに新たなインデックスエントリを追加する。リーフブロック２３０が拡張されているか否かは、後述する拡張ブロック操作部１５０から送られるデータに基づいて判断される。なお、データ挿入部１３０も、拡張ブロックをリーフブロック２３０のインデックスエントリを格納する領域の一部として扱う。
【００４８】
インデックスの更新では、リーフブロック２３０へのエントリの追加に加えて、ブランチブロック２２０にも新たなインデックスエントリを追加することが要求される場合がある。それは、挿入対象のリーフブロック２３０に、新たなインデックスエントリを追加するための十分な空き領域がない場合（オーバーフローが起きる場合）である。
【００４９】
このようにオーバーフローが起きる場合には、データ挿入部１３０は、ブロック分割を行うことによって空き領域を作る。ブロック分割では、データ挿入部１３０は、所定容量の空き領域がなくなったリーフブロック２３０のデータの一部を新たに確保したリーフブロック２３０に移すことで空き領域を作り出す。ブロック分割は、リーフブロック２３０のみでなくブランチブロック２２０においても同様に処理される。ブロック分割の詳細については動作例の項で詳述する。
【００５０】
データ削除部１４０は、削除する行データを特定するための値を受け取り、データブロック２４０から行データを削除し、削除された行データに対応するインデックスエントリをリーフブロック２３０から削除する。例えば、削除する行データを特定するための値は、検索部１２０の検索処理の結果として取得される。ここで、拡張ブロックは、リーフブロック２３０のインデックスエントリを格納する領域の一部として扱われるため、削除対象のインデックスエントリが実際には拡張ブロックに格納されている場合であっても、データ削除部１４０は、特定されたエントリを通常の処理と同様に削除する。
【００５１】
インデックスエントリをリーフブロック２３０又はその拡張ブロックから削除することにより、リーフブロック２３０又はその拡張ブロックの空き領域が所定サイズ以上となる場合（アンダーフローが起きる場合）、データ削除部１４０は、そのリーフブロック２３０が拡張されているか否かに応じて、以下のような処理を実行する。
【００５２】
データ削除部１４０は、そのリーフブロック２３０が拡張されていない場合には、このリーフブロック２３０を空きブロックにし、かつ、必要に応じて、ブロック統合処理を実行する。このブロック統合処理については動作例の項において詳述する。
【００５３】
一方、データ削除部１４０は、そのリーフブロック２３０が拡張されている場合には、拡張ブロックの統合処理を実行する。具体的には、データ削除部１４０は、そのリーフブロック２３０が拡張されている場合で、かつ、リーフブロック２３０自体にアンダーフローが起きると判定した場合には、拡張ブロック内のインデックスエントリをそのリーフブロック２３０に移動させる。データ削除部１４０は、そのリーフブロック２３０が拡張されている場合で、かつ、拡張ブロックにアンダーフローが起きると判定した場合には、同一リーフブロック２３０のための他の拡張ブロックに、その拡張ブロックのインデックスエントリを移動させる。
【００５４】
拡張ブロック操作部１５０は、データ挿入部１３０がブロック分割を行う前に、リーフブロック２３０のブロック分割を行うか、拡張ブロックを用いたリーフブロック２３０の容量の拡張を行うかのいずれか一方を選択する。この選択のために、拡張ブロック操作部１５０は、新たなインデックスエントリが追加されるリーフブロック２３０における全アクセスに対するライトアクセスの比率が所定閾値を超えるか否かを判定する。具体的には、拡張ブロック操作部１５０は、ライトカウンタの値（Ｗ）を、リードカウンタの値とライトカウンタの値との合計（Ｗ＋Ｒ）で除算することにより、当該ライトアクセスの比率（Ｗ／（Ｗ＋Ｒ））を算出する。
【００５５】
拡張ブロック操作部１５０は、当該ライトアクセスの比率が所定閾値を超える場合に、拡張ブロックを用いたリーフブロック２３０の容量の拡張を選択し、新たな拡張ブロックを取得する。拡張ブロック操作部１５０は、拡張ブロックを取得すると、その拡張ブロックへのポインタをリーフブロック２３０の拡張ポインタに設定する。一方、拡張ブロック操作部１５０は、当該ライトアクセスの比率が所定閾値以下である場合には、データ挿入部１３０にリーフブロック２３０のブロック分割を実行させる。
【００５６】
上記所定閾値は、例えば、予め調整可能にメモリ２に格納される。当該所定閾値には、例えば、全インデックスブロックにおけるライトアクセスの全アクセスに対する比率のｘパーセンタイル（ｘは例えば１０）等が用いられる。
【００５７】
拡張ブロック操作部１５０は、検索部１２０においてリーフブロック２３０が読み出された場合に、そのリーフブロック２３０の拡張ポインタ及び拡張ブロックの拡張ポインタを参照することにより、そのリーフブロック２３０のための全ての拡張ブロックを特定する。拡張ブロック操作部１５０は、それら拡張ブロックに含まれるエントリを検索対象とするように検索部１２０に指示する。
【００５８】
拡張ブロック操作部１５０は、データ削除部１４０により、リーフブロック２３０と拡張ブロックとの間、又は、拡張ブロック間におけるインデックスエントリの移動が実行される場合に、移動対象とする拡張ブロック及び移動対象とするインデックスエントリを特定する。リーフブロック２３０と拡張ブロックとの間、及び、拡張ブロック間におけるインデックスエントリの移動は、拡張ブロックを空ブロックとするように実行されることが好ましい。また、拡張ブロック操作部１５０は、インデックスエントリの移動により、リーフブロック２３０がオーバーフローしないように、移動させるインデックスエントリの数を決める。
【００５９】
アクセス管理部１１０は、データブロック２４０に対するデータ操作に応じてツリー構造に沿ってアクセスされた各インデックスブロックに関し、アクセスカウンタをそれぞれ更新する。具体的には、アクセス管理部１１０は、検索部１２０、データ挿入部１３０及びデータ削除部１４０によるインデックスブロックへのアクセス内容に基づいて、リードアクセス時にはそのインデックスブロックのリードカウンタを更新し、更新アクセス時にはそのインデックスブロックのライトカウンタを更新する。更新アクセスには、エントリの挿入操作及びエントリの削除操作が含まれる。なお、エントリの移動操作は、エントリの挿入操作とエントリの削除操作との組み合わせで実現される。
【００６０】
アクセス管理部１１０は、検索部１２０がインデックス検索を行うことによりインデックスエントリの識別子により特定されるブランチブロック２２０又はリーフブロック２３０を読み出す際に、その読み出されたインデックスブロックのブロックヘッダのアクセスカウンタを増加させる。但し、ルートブロックは最初に参照されるブロックであるため、検索部１２０は、アクセスした際に、ルートブロックのブロックヘッダのアクセスカウンタを増加させる。
【００６１】
アクセス管理部１１０は、検索部１２０がルートブロックのいずれかのエントリの識別子が示すブランチブロック２２０を読む際に、そのブランチブロック２２０のアクセスカウンタを１増加させる。更に、アクセス管理部１１０は、検索部１２０がこのブランチブロック２２０からたどるリーフブロック２３０にアクセスするときに、リーフブロック２３０のアクセスカウンタを１増加させる。
【００６２】
アクセス管理部１１０は、行データ挿入時においてデータ挿入部１３０により新たなインデックスエントリが追加されると、そのインデックスエントリが追加されたインデックスブロックのライトカウンタを１増加させる。このとき、アクセス管理部１１０は、そのインデックスエントリが追加されたインデックスブロックを検索するまでにアクセスされた各インデックスブロックのリードカウンタをそれぞれ１増加させる。
【００６３】
同様に、行データ挿入時においてブロック分割が行われる場合には、アクセス管理部１１０は、そのブロック分割処理においてアクセスされたインデックスブロックのリードカウンタを増加させ、かつ、ブロック分割処理でエントリが移動させられる度に移動先のインデックスブロックのライトカウンタを１増加させる。
【００６４】
また、アクセス管理部１１０は、データ削除部１４０がインデックスブロックからエントリを削除した場合には、そのインデックスブロックのライトカウンタを増加させる。更に、アクセス管理部１１０は、データ削除部１４０がインデックスブロックを空きブロックにする場合には、そのインデックスブロックを空きブロックにするために移動されたエントリの移動先となる他のインデックスブロックのライトカウンタを増加させる。
【００６５】
ここで、拡張ブロックは、リーフブロック２３０のインデックスエントリを格納する領域の一部として扱われるため、実際には拡張ブロック内のエントリが操作された場合であっても、その拡張ブロックを持つリーフブロック２３０のアクセスカウンタが更新される。具体的には、検索部１２０により拡張ブロック内のエントリが抽出された場合であっても、その拡張ブロックに対応するリーフブロック２３０のリードカウンタが更新される。同様に、データ挿入部１３０により拡張ブロックに新たなエントリが追加された場合、及び、データ削除部１４０により拡張ブロックのエントリが削除された場合であっても、その拡張ブロックに対応するリーフブロック２３０のライトカウンタが更新される。また、データ削除部１４０により拡張ブロックの統合処理が実行される場合には、拡張ブロック内のエントリを移動させる度に、その拡張ブロックに対応するリーフブロック２３０のライトカウンタが更新される。
【００６６】
〔動作例〕
以下、第１実施形態におけるＤＢシステム１０の動作例について図４から図７を用いて説明する。図４は、第１実施形態におけるＤＢシステム１０のデータ検索時の動作例を示すフローチャートである。図４の例では、完全一致検索を行う場合の動作が示される。図５は、ブランチブロック２２０、リーフブロック２３０及びデータブロック２４０の関係の例を概念的に示す図である。ここでは、図５の例において、文字列の大小を辞書順に従って比較することを想定し、検索部１２０が、検索キー「ｇｏ」を列データに含む行を検索する場合を例に挙げて、当該動作例を説明する。
【００６７】
検索部１２０は、検索キーを取得すると、まず、ルートブロックを読み出す（Ｓ１０）。図５の例では、検索部１２０は、検索キー「ｇｏ」を取得すると、キー値「ｅ」、「ｍ」、「ｔ」を含む各インデックスエントリを持つルートブロックを読み出す。
【００６８】
アクセス管理部１１０は、検索部１２０がルートブロックにアクセスした場合に、そのルートブロックのリードカウンタを１増加させる（Ｓ１１）。
【００６９】
検索部１２０は、ルートブロック内のインデックスエントリのうち、当該検索キー以下の最大のキー値を持つエントリ、又は、当該検索キー以上の最小のキー値を持つエントリを特定する。いずれの特定方法を取っても一般性を失わないので、ここでは、検索部１２０は、当該検索キー以下の最大のキー値を持つエントリを特定するものとする（Ｓ１２）。このエントリの特定は、ブロック中の全てのエントリを比較することにより実現されてもよいし、ブロック中のエントリをキー値でソートした上で一部のエントリを比較することにより実現されてもよい。
【００７０】
図５の例では、簡略化されているが、キー値「ｅ」については、例えば、キー値「ｅ」を持つエントリと「ｅ」より小さい値を示すキー値（例えば、ＮＵＬＬ）を持つエントリとが含まれる。ここで、検索キー「ｇｏ」以下の最大のキー値は「ｅ」であり、検索キー「ｇｏ」は、キー値「ｅ」より大きくキー値「ｍ」よりも小さいので、左から２番目のブランチブロックを特定する識別子を含むエントリが特定される。
【００７１】
続いて、検索部１２０は、そのように特定されたエントリの識別子によって特定されるインデックスブロックを読み出す（Ｓ１３）。
【００７２】
アクセス管理部１１０は、検索部１２０がインデックスブロックを読み出すと、そのインデックスブロックのリードカウンタを１増加させる（Ｓ１４）。
【００７３】
検索部１２０は、ブロックヘッダに設定されるブロック種により、その読み出されたインデックスブロックがリーフブロック２３０かブランチブロック２２０かを判定する（Ｓ１５）。検索部１２０及びアクセス管理部１１０は、その読み出されたインデックスブロックがブランチブロック２２０である場合には（Ｓ１５；ＮＯ）、その読み出されたブランチブロック２２０に関し上記（Ｓ１２）、（Ｓ１３）及び（Ｓ１４）の処理を実行する。
【００７４】
検索部１２０は、その読み出されたインデックスブロックがリーフブロック２３０である場合には（Ｓ１５；ＹＥＳ）、その読み出されたリーフブロック２３０内のエントリを取得する（Ｓ１６）。図５の例では、リーフブロック２３０内のエントリ（キー値「ｇａｍｅ」を含むエントリからキー値「ｇｉｆｔ」を含むエントリまで）が取得される。
【００７５】
続いて、拡張ブロック操作部１５０が、その読み出されたリーフブロック２３０の拡張ポインタが無効か否かを判定する（Ｓ１７）。この判定は、拡張ポインタに有効値が設定されているか否かにより行われる。拡張ブロック操作部１５０は、拡張ポインタが有効であると判定すると（Ｓ１７；ＮＯ）、その拡張ポインタにより特定される拡張ブロック内のエントリを取得する（Ｓ１８）。図５の例では、リーフブロック２３０の拡張ブロック内のエントリ（キー値「ｇｉｖｅ」を含むエントリからキー値「ｈｅａｒ」を含むエントリまで）が取得される。
【００７６】
拡張ブロック操作部１５０は、その拡張ブロック内の拡張ポインタに有効値が設定されている場合には、更に、その拡張ポインタで特定される他の拡張ブロック内のエントリも取得する。このようにして、拡張ブロック操作部１５０は、その読み出されたリーフブロック２３０のための各拡張ブロック内のエントリをそれぞれ取得する（Ｓ１８）。なお、リーフブロック２３０の拡張ポインタが無効であると判定すると（Ｓ１７；ＹＥＳ）、検索部１２０は、処理（Ｓ２０）を実行する。
【００７７】
検索部１２０は、処理（Ｓ１６）で取得されたリーフブロック２３０内のエントリ、及び、処理（Ｓ１８）で取得された拡張ブロック内のエントリの中から、検索キーを含む検索条件に一致するエントリを特定する（Ｓ２０）。ここでは、その検索条件は、検索キーを列データに含む行（完全一致）の検索を示す。図５の例では、キー値「ｇｏ」を含むインデックスエントリが特定される。
【００７８】
このインデックスエントリの特定は、リーフブロック２３０及びそのリーフブロック２３０が持つ拡張ブロック内の全てのエントリを比較することにより実現されてもよいし、それらエントリをキー値でソートした上で一部のエントリを比較することにより実現されてもよい。
【００７９】
検索部１２０は、特定されたインデックスエントリに含まれる識別子で特定される行データを抽出する（Ｓ２１）。図５の例では、キー値「ｇｏ」を含むインデックスエントリの識別子により特定されるデータブロック２４０の行が抽出される。例えば、その識別子に含まれるポインタで、行データの先頭が特定され、その先頭アドレスから行の大きさ（バイト数）分のデータが読み出される。
【００８０】
図６は、第１実施形態におけるＤＢシステム１０のデータ挿入時の動作例を示すフローチャートである。
【００８１】
データ挿入部１３０は、挿入すべき行データを取得すると、この行データを空き領域のある任意のデータブロック２４０に書き込む（Ｓ３１）。
【００８２】
データ挿入部１３０は、挿入された行データに対応するインデックスエントリを挿入すべきリーフブロック２３０を特定する（Ｓ３２）。このリーフブロック２３０の特定は、挿入された行データにおけるキーが設定された列の値を検索キーとしたインデックス検索によりリーフブロック２３０を特定する場合と同様の手法で実現される。図４の動作例によれば、（Ｓ１０）、（Ｓ１１）、（Ｓ１２）、（Ｓ１３）、（Ｓ１４）及び（Ｓ１５）の処理が実行されることにより、挿入すべきリーフブロック２３０が特定される。
【００８３】
このとき、挿入された行データに対応するリーフブロック２３０を特定するために読み出されたインデックスブロックのリードカウンタは、アクセス管理部１１０によりカウントアップされる。
【００８４】
続いて、データ挿入部１３０は、特定されたリーフブロック２３０に挿入すべき新たなインデックスエントリを生成する（Ｓ３３）。新たなインデックスエントリは、挿入された行データにおけるキーが設定された列の値をキー値として含み、挿入された行データを特定するための識別子を含む。
【００８５】
データ挿入部１３０は、特定されたリーフブロック２３０が新たなインデックスエントリの追加によりオーバーフローするか否かを判定する（Ｓ３４）。ここで、オーバーフローとは、新たなインデックスエントリを追加するとブロックの空き領域が所定の比率を下回ることである。
【００８６】
データ挿入部１３０は、オーバーフローしないと判定すると（Ｓ３４；ＮＯ）、その特定されたリーフブロック２３０にその新たに生成されたインデックスエントリを書き込む（Ｓ３５）。このとき、アクセス管理部１１０は、書き込まれたリーフブロック２３０のライトカウンタを１増加させる（Ｓ３６）。
【００８７】
続いて、データ挿入部１３０は、ブロック分割がなされたか否かを判定する（Ｓ３７）。データ挿入部１３０は、ブロック分割がされていない場合には（Ｓ３７；ＮＯ）、処理を終了し、ブロック分割がなされている場合には（Ｓ３７；ＹＥＳ）、ブロック分割がなされたブロックの上位のブランチブロックを特定する（Ｓ３８）。この上位ブランチブロックの特定は、再帰関数的な処理を施すことにより実現してもよいし、ブロックヘッダに上位ブロックの識別子を格納することで実現してもよい。
【００８８】
以降、データ挿入部１３０は、その特定された上位ブランチブロックを対象ブロックとして処理（Ｓ３３）に戻って各処理を実行する。
【００８９】
一方、データ挿入部１３０は、オーバーフローすると判定した場合には（Ｓ３４；ＹＥＳ）、そのオーバーフローすると判定されたインデックスブロックがリーフブロック２３０であるか否かを判定する（Ｓ４０）。
【００９０】
対象のインデックスブロックがリーフブロック２３０でない場合には（Ｓ４０；ＮＯ）、データ挿入部１３０は、その対象のインデックスブロックに対してブロック分割処理を実行する。
【００９１】
ブロック分割処理では、まず、データ挿入部１３０は、オーバーフローすると判定されたインデックスブロックがルートブロックか否かを判定する（Ｓ５０）。データ挿入部１３０は、当該インデックスブロックがルートブロックである場合（Ｓ５０；ＹＥＳ）、新たなルートブロックとするための新たな空きブロックを取得する（Ｓ５１）。このとき、アクセス管理部１１０は、取得された空きブロックのリードカウンタを１増加させる（Ｓ５２）。
【００９２】
データ挿入部１３０は、オーバーフローすると判定された現在のルートブロック内の最小のキー値及び現在のルートブロックを特定するための識別子を含むインデックスエントリを生成する（Ｓ５３）。データ挿入部１３０は、このように生成されたインデックスエントリを、新たなルートブロックとするために取得された空きブロックに書き込む（Ｓ５４）。言い換えれば、生成されたインデックスエントリは、新たなルートブロックから元のルートブロック（その後のブランチブロック）へリンクするためのデータとなる。
【００９３】
このとき、アクセス管理部１１０は、そのインデックスエントリが書き込まれたインデックスブロックのライトカウンタを１増加させる（Ｓ５５）。
【００９４】
続いて、データ挿入部１３０は、ルートブロックを変更する（Ｓ５６）。具体的には、データ挿入部１３０は、オーバーフローすると判定された元のルートブロックから新たに取得されたブロックに、ルートブロックを変更する。例えば、この変更は、ブロックヘッダのブロック種の変更により実現される。
【００９５】
次に、データ挿入部１３０は、空きブロックを更に取得する（Ｓ５７）。データ挿入部１３０は、そのオーバーフローすると判定されたインデックスブロック内の移動させるべきエントリを決定し、決定された各エントリを上記取得された空きブロックに順次移動させる（Ｓ５８）。例えば、データ挿入部１３０は、予め閾値を保持しており、オーバーフローすると判定されたインデックスブロックのエントリのうち、当該閾値以上のキー値を持つエントリを移動エントリに決定する。その閾値には、中央値などのような、１つ以上のエントリのキー値よりも小さい値を用いる。
【００９６】
このとき、アクセス管理部１１０は、エントリを空きブロックに移すたびに、空きブロックのライトカウンタを１増加させる（Ｓ５９）。
【００９７】
その後、データ挿入部１３０は、エントリの移動によりできた空き領域に処理（Ｓ３３）で生成されたインデックスエントリを書き込む（Ｓ３５）。以降、データ挿入部１３０及びアクセス管理部１１０は、上述した処理（Ｓ３６）以降の各処理を実行する。
【００９８】
一方、データ挿入部１３０は、オーバーフローすると判定されたインデックスブロックがリーフブロック２３０である場合には（Ｓ４０；ＹＥＳ）、更に、そのリーフブロック２３０が拡張されているか否かを確認する（Ｓ４１）。具体的には、データ挿入部１３０は、そのリーフブロック２３０の拡張ポインタが有効であるか否かを拡張ブロック操作部１５０に判定させる（Ｓ４１）。データ挿入部１３０は、そのリーフブロック２３０が拡張されている場合には（Ｓ４１；ＹＥＳ）、更に、そのリーフブロック２３０が、処理（Ｓ３３）で生成されたインデックスエントリを挿入したとしてもオーバーフローしない拡張ブロックを持つか否かを判定する（Ｓ４２）。このとき、拡張ブロック操作部１５０は、そのリーフブロック２３０の拡張ポインタを参照することにより、リーフブロック２３０のための拡張ブロックを特定する。
【００９９】
データ挿入部１３０は、そのリーフブロック２３０がオーバーフローしない拡張ブロックを持つ場合には（Ｓ４２；ＹＥＳ）、その拡張ブロックをインデックスエントリ挿入のための対象ブロックに設定する（Ｓ４３）。一方、拡張ブロック操作部１５０は、そのリーフブロック２３０が拡張されているがオーバーフローしない拡張ブロックを持たない場合（Ｓ４２；ＮＯ）、新たな拡張ブロックを取得し、その取得された拡張ブロックをインデックスエントリ挿入のための対象ブロックに設定する（Ｓ４５）。このとき、拡張ブロック操作部１５０は、その取得された拡張ブロックを特定するためのポインタを拡張ポインタとしてそのリーフブロック２３０又は既に存在する拡張ポインタに設定する（Ｓ４５）。
【０１００】
拡張ブロック操作部１５０は、そのリーフブロック２３０が拡張されていない場合（Ｓ４１；ＮＯ）、そのリーフブロック２３０における全アクセスに対するライトアクセスの比率を算出する。拡張ブロック操作部１５０は、算出されたライトアクセスの比率が所定閾値を超えるか否かを判定する（Ｓ４４）。
【０１０１】
拡張ブロック操作部１５０は、ライトアクセスの比率が所定閾値を超えない場合（Ｓ４４；ＮＯ）、データ挿入部１３０に、そのリーフブロック２３０に対して上述したようなブロック分割処理を実行させる。これにより、データ挿入部１３０は、上述した処理（Ｓ５７）、（Ｓ５８）及び（Ｓ５９）を実行する。
【０１０２】
一方、拡張ブロック操作部１５０は、ライトアクセスの比率が所定閾値を超える場合（Ｓ４４；ＹＥＳ）、新たな拡張ブロックを取得し、その取得された拡張ブロックをインデックスエントリ挿入のための対象ブロックに設定する（Ｓ４５）。このとき、拡張ブロック操作部１５０は、その取得された拡張ブロックを特定するためのポインタを拡張ポインタとしてそのリーフブロック２３０又は既に存在する拡張ポインタに設定する（Ｓ４５）。
【０１０３】
その後、データ挿入部１３０は、上述の処理（Ｓ４３）又は（Ｓ４５）でインデックスエントリ挿入のための対象ブロックに設定された拡張ブロックに、処理（Ｓ３３）で生成されたインデックスエントリを書き込む（Ｓ３５）。以降、データ挿入部１３０及びアクセス管理部１１０は、上述した処理（Ｓ３６）以降の各処理を実行する。なお、当該拡張ブロックに新たなインデックスエントリが書き込まれた場合においても、データ挿入部１３０は、その拡張ブロックに対応するリーフブロック２３０のライトブロックを更新する。
【０１０４】
図７は、第１実施形態におけるＤＢシステム１０のデータ削除時の動作例を示すフローチャートである。
【０１０５】
データ削除部１４０は、削除する行データを特定するための値を受け取り、データブロック２４０から行データを削除する（Ｓ６１）。行データの削除は、行のデータを消去することで実現してもよいし、その行データに無効を示す値を付加することで実現してもよい。
【０１０６】
データ削除部１４０は、削除された行データを特定するインデックスエントリを有するリーフブロック２３０を特定する（Ｓ６２）。このリーフブロック２３０の特定は、削除された行データにおけるキーが設定された列の値を検索キーとしたインデックス検索によりリーフブロック２３０を特定する場合と同様の手法で実現される。図４の動作例によれば、（Ｓ１０）、（Ｓ１１）、（Ｓ１２）、（Ｓ１３）、（Ｓ１４）及び（Ｓ１５）の各処理が実行されることにより、当該リーフブロック２３０が特定される。
【０１０７】
データ削除部１４０は、特定されたリーフブロック２３０における、削除された行データに対応するインデックスエントリを削除する（Ｓ６３）。このとき、特定されたリーフブロック２３０が拡張されている場合には、データ検索時の処理と同様に、リーフブロック２３０及び拡張ブロック内の全エントリを対象にして、削除対象となるインデックスエントリが特定される。更に、このとき、アクセス管理部１１０は、そのインデックエントリが削除されたリーフブロック２３０のライトカウンタを増加させる（Ｓ６４）。削除されたインデックスエントリが拡張ブロック内に存在していたとしても、その拡張ブロックに対応するリーフブロック２３０のライトカウンタが更新される。
【０１０８】
データ削除部１４０は、エントリを削除したリーフブロック２３０又は拡張ブロックがアンダーフローするか否かを判定する（Ｓ６５）。データ削除部１４０は、アンダーフローが起きていなければ（Ｓ６５；ＮＯ）、処理を終了する。
【０１０９】
拡張ブロック操作部１５０は、データ削除部１４０により、アンダーフローすると判定された場合には（Ｓ６５；ＹＥＳ）、削除対象として特定されたリーフブロック２３０の拡張ポインタに無効値が設定されているか否かを判定する（Ｓ６６）。データ削除部１４０は、拡張ポインタに無効値が設定されている場合には（Ｓ６６；ＹＥＳ）、リーフブロック２３０に残るエントリを、他のリーフブロック２３０に移動させ、そのリーフブロック２３０を空きブロックにする（Ｓ６７）。このとき、アクセス管理部１１０は、エントリを移動させた先のリーフブロック２３０のライトカウンタを１増加させる（Ｓ６８）。
【０１１０】
なお、移動先ブロックは、一つであってもよいし、複数あってもよく、任意の方法で選択すればよい。また、移動先のリーフブロック２３０が拡張されている場合には、その移動先のリーフブロック２３０のための拡張ブロックを移動先ブロックに選択してもよい。この場合においても、拡張ブロックは、リーフブロック２３０のインデックスエントリを格納する領域の一部として扱われるため、移動されたエントリの格納される領域が実際には拡張ブロック内であったとしても、そのエントリ移動処理は、通常のエントリ移動処理と同様の処理で実現可能である。
【０１１１】
データ削除部１４０は、空きブロックとなったリーフブロック２３０のアクセスカウンタ（リードカウンタ及びライトカウンタ）を０に設定する。空きブロックとすることで、このブロックはデータ挿入部１３０又は拡張ブロック操作部１５０によって再利用される。また、空きブロック化されたリーフブロック２３０のアクセスカウンタは、それぞれ移動先のブロックのアクセスカウンタに合算されてもよい。
【０１１２】
続いて、データ削除部１４０は、ブロック統合が可能か否か判定する（Ｓ６９）。具体的には、データ削除部１４０は、空きブロック化されたリーフブロック２３０の親ブロック（ブランチブロック２２０）にぶら下がる全子ブロックの全エントリをその親ブロックに入れることができるか否かを判定する（Ｓ６９）。
【０１１３】
データ削除部１４０は、ブロック統合が不可能と判定すると（Ｓ６９；ＮＯ）、処理を終了する。一方、データ削除部１４０は、ブロック統合が可能と判定すると（Ｓ６９；ＹＥＳ）、それらブロックを統合する（Ｓ７０）。つまり、子ブロックの全エントリを親ブロックに移しつつ、親ブロックに存在したエントリは削除する。結果、その親ブロックにぶら下がる全ての子ブロックが空きブロックとされる。
【０１１４】
このとき、アクセス管理部１１０は、上位ブロックのライトカウンタを１増加させる（Ｓ７１）。なお、統合される子ブロックのアクセスカウンタの値は、親ブロックのアクセスカウンタに合算されてもよい。
【０１１５】
一方で、削除対象として特定されたリーフブロック２３０の拡張ポインタに有効値が設定されている場合には（Ｓ６６；ＮＯ）、拡張ブロック操作部１５０が、移動対象のエントリ及び移動先を特定し、データ削除部１４０が当該移動対象のエントリを当該移動先のブロックに順次移動させる（Ｓ７２）。これにより、アンダーフローしているリーフブロック２３０に関し、拡張ブロック間、又は、拡張ブロックとそのリーフブロック２３０との間で、エントリの移動が実行される。
【０１１６】
このとき、拡張ブロック操作部１５０は、リーフブロック２３０自体がアンダーフローしている場合には、拡張ブロック内のインデックスエントリを移動対象に決定し、アンダーフローしているリーフブロック２３０を移動先に決定する。また、拡張ブロック操作部１５０は、拡張ブロックがアンダーフローしている場合には、その拡張ブロック内のエントリを移動対象に決定し、同一リーフブロック２３０のための他の拡張ブロックを移動先に決定する。
【０１１７】
アクセス管理部１１０は、エントリの移動が行われる度に、対応するリーフブロック２３０のライトカウンタを増加させる（Ｓ７３）。
【０１１８】
〔第１実施形態の作用及び効果〕
このように第１実施形態では、各インデックスブロックには、リードカウンタとライトカウンタとがそれぞれ設けられ、データブロック２４０に対するデータ操作に応じて、検索部１２０、データ挿入部１３０及びデータ削除部１４０によりアクセスされたインデックスブロックのリードカウンタ及びライトカウンタがアクセス管理部１１０により更新される。このように、第１実施形態によれば、各インデックスブロックへのアクセス回数が、リードアクセスとライトアクセスとで区別されそれぞれ管理される。
【０１１９】
更に、第１実施形態では、データ挿入部１３０によりデータ挿入処理が実行される際に、拡張ブロック操作部１５０により、挿入対象のリーフブロック２３０における全アクセスに対するライトアクセスの比率が所定閾値を超えるか否かが判定され、ライトアクセスの比率が所定閾値を超える場合に、そのリーフブロック２３０に拡張ブロックが追加される。この拡張ブロックは、インデックスブロックとは異なり、他のブロック内のインデックスエントリにより特定されず、リーフブロック２３０の拡張ポインタで特定される。
【０１２０】
この拡張ブロックは、検索部１２０、データ挿入部１３０及びデータ削除部１４０によるインデックスエントリの操作において、この拡張ブロックを特定するための拡張ポインタが設定されたリーフブロック２３０のインデックスエントリを格納する領域の一部として扱われる。また、リーフブロック２３０がアンダーフローする場合には、そのリーフブロック２３０と拡張ブロックとの間、又は、拡張ブロック間でブロック統合が実施される。
【０１２１】
このように、第１実施形態によれば、ライトアクセスの比率が大きいリーフブロック２３０がオーバーフローすると判定された場合には、そのリーフブロック２３０には、他のブロック内にそれを特定するためのインデックスエントリを設定しなくてもよい拡張ブロックが追加され、リーフブロック２３０のインデックスエントリを格納するための領域が拡張される。
【０１２２】
従って、第１実施形態によれば、他のブロックのエントリに影響を与えない拡張ブロックを用いることにより、データ挿入速度を向上させることができる。ところが、拡張ブロックを用いた場合、検索対象となるエントリが増加することになるため、拡張ブロックにより拡張されたリーフブロック２３０に対する検索速度は低下することになる。そこで、第１実施形態では、ライトアクセスが集中するブロックのみを対象に拡張ブロックを付加することにより、システム全体のパフォーマンスを最適化することができる。なお、上述したｒｉｇｈｔ−ｇｒｏｗｉｎｇ  ｉｎｄｅｘは、インデックスブロック間でライトアクセスの比率に差が生じる典型例である。
【０１２３】
［第２実施形態］
以下、第２実施形態におけるＤＢシステム１０について説明する。第２実施形態は、上述の第１実施形態の構成に加えて、上記拡張ブロックを、リードアクセスの比率に応じて、リーフブロック２３０となるように設定する構成を更に有する。第２実施形態では、ＤＢシステム１０の構成は上述の第１実施形態と同様であるが、各処理部の処理が第１実施形態と異なる。以下、第２実施形態におけるＤＢシステム１０について、第１実施形態と異なる内容を中心に説明し、第１実施形態と同一の内容についての説明は適宜省略する。
【０１２４】
拡張ブロック操作部１５０は、拡張ブロックを持つリーフブロック２３０に関し、全アクセスに対するリードアクセスの比率が所定閾値を超えるか否かを判定し、リードアクセスの比率が所定閾値を超える場合に、当該拡張ブロックをリーフブロック２３０となるように設定する。具体的には、拡張ブロック操作部１５０は、リードカウンタの値（Ｒ）を、リードカウンタの値とライトカウンタの値との合計（Ｒ＋Ｗ）で除算することにより当該リードアクセスの比率（Ｒ／（Ｒ＋Ｗ））を算出する。なお、拡張ブロックをリーフブロック２３０となるように設定する処理の詳細については、動作例の項において説明する。
【０１２５】
リードアクセスの比率と比較される所定閾値は、第１実施形態におけるライトアクセスの比率との比較で利用された所定閾値と共に、予め調整可能にメモリ２に格納される。リードアクセスの比率と比較される所定閾値についても、例えば、全インデックスブロックにおけるリードアクセスの全アクセスに対する比率のｘパーセンタイル（ｘは例えば１０）等が用いられる。なお、リードアクセスの比率と比較される所定閾値と、第１実施形態におけるライトアクセスの比率との比較で利用された所定閾値とは１つの値であってもよい。
【０１２６】
〔動作例〕
図８は、第２実施形態におけるＤＢシステム１０の動作例を示すフローチャートである。図８では、第１実施形態におけるＤＢシステム１０のデータ検索時と同じ処理については図４と同じ符号が付されている。
【０１２７】
第２実施形態におけるＤＢシステム１０は、データ検索時において、第１実施形態と同様の処理（Ｓ１０）から処理（Ｓ２１）を実行する。インデックスエントリに含まれる識別子で特定される行データが検索部１２０により抽出されると（Ｓ２１）、拡張ブロック操作部１５０は、特定されたリーフブロック２３０の拡張ポインタに有効値が設定されているか否か、かつ、リードアクセスの比率が所定閾値を超えているか否かを判定する（Ｓ８１）。
【０１２８】
拡張ブロック操作部１５０は、特定されたリーフブロック２３０の拡張ポインタに無効値が設定されている、又は、リードアクセスの全アクセスに対する比率が所定閾値以下である場合には（Ｓ８１；ＮＯ）、処理を終了する。一方、拡張ブロック操作部１５０は、特定されたリーフブロック２３０の拡張ポインタに有効値が設定されており、かつ、リードアクセスの比率が所定閾値を超えている場合には（Ｓ８１；ＹＥＳ）、そのリーフブロック２３０が有する拡張ブロックをインデックスブロックとなるように設定する（Ｓ８２）。
【０１２９】
処理（Ｓ８２）において、拡張ブロック操作部１５０は、リーフブロック２３０内のその拡張ブロックを特定するための拡張ポインタに無効値を設定する。更に、拡張ブロック操作部１５０は、その拡張ブロックを図３に示される形態に設定する。例えば、拡張ブロック操作部１５０は、ブロックヘッダを、ブロック種がリーフブロック２３０を示すように設定し、ブロックヘッダにリードカウンタ及びライトカウンタを設ける。なお、拡張ブロックにも、予め、リーフブロック２３０と同様のブロックヘッダが設けられていてもよい。この場合には、拡張ブロックのブロックヘッダは、拡張ポインタ以外利用されなければよい。
【０１３０】
拡張ブロック操作部１５０は、更に、リーフブロック２３０及びそのリーフブロック２３０の拡張に利用される拡張ブロックに格納される全エントリをキー値を用いてソートし、最も小さいキー値を持つエントリから所定数のエントリをリーフブロック２３０に格納し、それ以降のエントリを拡張ブロックに格納する。上記所定数は、例えば、全エントリの数を、リーフブロック２３０及び拡張ブロックの数で割った値に設定される。
【０１３１】
拡張ブロック操作部１５０は、上述のようなエントリのソートをした後、データ挿入部１３０に、その拡張ブロックを特定するための識別子を含むインデックスエントリをブランチブロック２２０に追加するように指示する。これにより、データ挿入部１３０は、その拡張ブロックを対象にして、ブロック分割により生じた新たなブロックを挿入する処理と同様の処理を実行する。具体的には、データ挿入部１３０は、図６に示される処理（Ｓ３８）以降の処理を実行する。
【０１３２】
リーフブロック２３０が複数の拡張ブロックにより拡張されている場合には、上述のような処理（Ｓ８２）は、それら全ての拡張ブロックを対象に実行される。
【０１３３】
また、上述のような拡張ブロックをインデックスブロックとなるように設定する処理（Ｓ８１）及び（Ｓ８２）は、図８のフローチャートで示される処理の順番に限定されない。例えば、検索部１２０により処理（Ｓ２１）が実行されるのと並行して、処理（Ｓ８１）及び（Ｓ８２）が実行されてもよい。更に、当該処理（Ｓ８１）及び（Ｓ８２）は、データ検索処理とは無関係に、任意のタイミング（例えば、周期的）で、全リーフブロック２３０を対象に実行されてもよい。
【０１３４】
〔第２実施形態における作用及び効果〕
このように第２実施形態では、データ挿入速度を向上させるために追加された拡張ブロックが、リードアクセスの比率が所定閾値を超える場合に、リーフブロック２３０となるように設定される。即ち、第２実施形態では、ライトアクセスの比率が大きいリーフブロック２３０には拡張ブロックが付加され、そのリーフブロック２３０のリードアクセスの比率が大きくなると、その拡張ブロックがリーフブロック２３０となるように設定される。
【０１３５】
リーフブロック２３０及びブランチブロック２２０には近い値を持つキーが格納されるため、特定の範囲のキーが頻繁に挿入される場合、対応するブロックにはライトアクセスが集中する。一方、特定の範囲のキーが頻繁に検索されれば、対応するブロックにはリードアクセスが集中する。したがって、インデックスを張ることで検索速度を向上させるべきブロックとインデックスを張らずに挿入速度を向上させるべきブロックが存在し得る。
【０１３６】
第２実施形態によれば、アクセス比率に応じてインデックスを張るブロックとインデックスを張らないブロック（拡張ブロック）とを決めているため、ライトアクセスが多いブロックとリードアクセスが多いブロックが混在していても、効率的にデータを処理することができる。言い換えれば、キーの値の範囲によってリードとライトのアクセス比率が異なる場合でも、高い処理性能が実現され得る。更に、第２実施形態によれば、アクセス比率の変化に動的に追随できるために、ワークロードが変化しても十分な性能を達成することができる。
【０１３７】
上述のような第１実施形態及び第２実施形態における作用効果を具体例に基づいて以下に説明する。例えば、データブロック２４０が売上明細表を格納し、その売上明細表の中の商品番号がキー値に設定され、その売上明細表に対して、売上明細の挿入及び検索（集計）の各処理が発生する例を想定する。また、この例において、各リーフブロック２３０に５パーセント（％）から１５％の比率でライトアクセスがそれぞれ発生し、リーフブロック２３０を拡張するか否かの判断に用いられる所定閾値が２５％に設定されていると仮定する。
【０１３８】
この例において、商品番号「１３００」の商品の特売がされた場合、この特売商品の売り上げが増加すれば、例えば、商品番号「１０００」から商品番号「１９９９」までの商品の売り上げを記録しているリーフブロック２３０へのライトアクセス（行の挿入操作）が増加する。このとき、定常的なリードアクセスに大きな変化はなく、ライトアクセスの比率が３０％まで増加した場合、上記リーフブロック２３０には拡張ブロックが付加される。
【０１３９】
本実施形態によれば、このような一時的かつ部分的なライトアクセスの増加に対して、自動的に、ライトアクセスに対する処理の高速化とリードアクセスに対する処理の低速化とが実現される。そして、本実施形態によれば、増加したライトアクセスに対する処理が高速化された結果、システム全体としての性能が向上する。逆に、特売が終了することにより、ライトアクセスの比率が下がれば、拡張ブロックは、通常のリーフブロック２３０となるように設定されるため、インデックスが付与されることにより、リードアクセスに対する処理の高速化が実現される。
【０１４０】
また、本実施形態は、ｒｉｇｈｔ−ｇｒｏｗｉｎｇ  ｉｎｄｅｘの問題にも有効である。例えば、データブロック２４０に格納されるデータ表が現在時刻を示す列を持ち、この現在時刻の列がキーに設定される場合、最も新しい時刻を示す一番右側のリーフブロック２３０にライトアクセスが集中する。本実施形態では、このリーフブロック２３０に拡張ブロックが付与されるため、現在時刻を更新するためのライトアクセスに対する処理を高速化することができる。
【０１４１】
一方で、このリーフブロック２３０と拡張ブロックとを１回検索するのに発生するリードアクセスの数は、拡張ブロックの増加に伴って増加する。例えば、或るリーフブロック２３０に９つの拡張ブロックが付加されていたとすると、１回の検索で、１０回のリードアクセスが発生する。これに対して、１行を挿入するのに発生するライトアクセスは基本的には１回であるため、ライトアクセスの比率は下がる傾向にある。当該比率が或る程度まで下がると、拡張ブロックはリーフブロック２３０となるように設定される。その結果、一番右側には新たなリーフブロック２３０が追加され、より最近の時刻を示すキーが挿入される。一般に、ブロックの挿入は、１つずつよりもまとめた方が効率的に処理できることを注記する。
【０１４２】
［変形例］
上述の第１実施形態では、リーフブロック２３０を拡張するか否かの判断は、そのリーフブロック２３０における全アクセスに対するライトアクセスの比率と所定閾値との比較結果に基づいて実施されたが、単に、ライトカウンタがリードカウンタより多い場合に、リーフブロック２３０を拡張すると判断するようにしてもよい。また、リードカウンタに対するライトカウンタの比率と所定閾値との比較により、リーフブロック２３０を拡張するか否かの判断が実施されてもよい。
【０１４３】
また、上述の第２実施形態では、拡張ブロックをリーフブロック２３０となるように設定するか否かの判断は、そのリーフブロック２３０における全アクセスに対するリードアクセスの比率と所定閾値との比較結果に基づいて実施されたが、単に、リードカウンタがライトカウンタより多い場合に、拡張ブロックをリーフブロック２３０となるように設定すると判断するようにしてもよい。また、ライトカウンタに対するリードカウンタの比率と所定閾値との比較により、拡張ブロックをリーフブロック２３０となるように設定するか否かの判断が実施されてもよい。
【０１４４】
また、上述の各実施形態では、リーフブロック２３０及び各拡張ブロックには１つの拡張ポインタがそれぞれ設けられたが、拡張ブロックには拡張ポインタを設けず、リーフブロック２３０に複数の拡張ポインタを設けるようにしてもよい。
【０１４５】
また、上述の各実施形態では、アクセスカウンタ（リードカウンタ及びライトカウンタを含む）は１ずつ増やされたが、この増加幅は、アクセス種別等に応じて適宜変えてもよい。
【０１４６】
なお、上記各実施形態の説明は、複数のフローチャートを用いており、それぞれに複数のステップ（処理）を順番に記載しているが、本実施形態は、各ステップの順番を図示される順番に限定するものではない。本実施形態では、図示される処理ステップの順番を内容的に支障しない範囲で変更することができる。また、上述した各実施形態及び変形例は、その内容が相反しない範囲で組み合わせることができる。
【０１４７】
この出願は、２０１１年２月２２日に出願された日本出願特願２０１１−０３５４３７を基礎とする優先権を主張し、その開示の全てをここに取り込む。
【図１】
2012114402.tif 000003
【図２】
2012114402.tif 000004
【図３】
2012114402.tif 000005
【図４】
2012114402.tif 000006
【図５】
2012114402.tif 000007
【図６】
2012114402.tif 000008
【図７】
2012114402.tif 000009
【図８】
2012114402.tif 000010
【国際調査報告】
2012114402.tif 000011
2012114402.tif 000012