ヘッダーをスキップ
Oracle Databaseデータ・カートリッジ開発者ガイド
11gリリース1(11.1)
E05688-02
  目次
目次
索引
索引

戻る
戻る
次へ
次へ
 

7 拡張可能索引付けの使用

この章では、拡張可能索引付けについて説明します。この機能を使用すると、Oracle組込みの索引付けモードに加えて、組み込まれていない索引付けモードを追加実装できます。この章で説明するのは、ドメイン索引を作成する際の決定に役立つ概念上の背景です。ドメイン索引は、拡張可能索引付けフレームワークを使用して作成される索引です。

この章の内容は、次のとおりです。

拡張可能索引付けの概要

この項では、索引の作成に使用する用語と方法について説明します。経験豊富なデータベース・アプリケーション開発者は、この説明のほとんどをよく理解しています。ここで説明するのは、他の分野の経験を持つユーザーの参考のためと、用語と方法論についてベースラインを確立するためです。

索引の目的

データベースに含まれるような大量のデータの場合、索引を使用するとデータの検索と取出しが高速かつ効率的になります。データベース内のレコードを参照するかテクニカル・マニュアルの本文を参照するかに関係なく、索引エントリは参照先項目について次の3つのことを示します。

  • 項目の内容(「Mary Leeの従業員情報」や「拡張可能索引付けの定義」など)

  • 項目の場所(「レコード番号1000」または「100ページ」など)

  • 項目の格納方法(「連続するレコード内」または「ページ本文」など)

ほとんどのデータ・セットは複数の異なる方法で索引付けできます。最も有用で効率的なデータ・アクセスを提供するには、通常、適切な索引付け形式を選択することが重要です。これは、すべてのアプリケーションにとって最適な索引付け方法は存在しないためです。

通常、データベース・アプリケーションは問合せでデータを取り出します。問合せでは使用可能なデータのサブセットの選択に索引を使用します。問合せはその表現で使用する演算子に応じて大きく異なる場合があるため、最適なアクセスを提供する索引付け方法も異なります。

  • サンフランシスコ支社に所属している営業担当を確認するには、等価性をチェックする演算子が必要です。ハッシュ構造では、等価演算子がきわめて効果的に処理されます。

  • 所得がxを超えていてy未満の営業担当を確認するには、範囲をチェックする演算子が必要です。範囲指向の問合せを処理するには、Bツリー構造の方が適しています。

拡張可能索引付けの目的

データベースには、医療アプリケーションやマルチメディア・アプリケーションのように、より複雑で特定のタスクに限定された新しいタイプの情報が継続的に取り込まれています。その結果、問合せはますます複雑になり、スキャンする必要のあるデータ量も増大を続けています。Oracleには拡張可能索引付けフレームワークが用意されているため、索引付け方法をデータとアプリケーションにあわせて調整でき、パフォーマンスと使いやすさを向上させることができます。

拡張可能索引付けを使用する場合、アプリケーションでは次の操作を実行します。

  • 索引の構造を定義します。

  • Oracleデータベース内(索引構成表形式など)またはOracleデータベース外に索引データを格納します。

  • 索引データを管理し、取り出してユーザー問合せの評価に使用します。

したがって、アプリケーションでは索引の構造とセマンティックの内容を制御することになります。データベース・システムはアプリケーションと共同でドメイン索引を作成、維持し、使用します。その結果、索引を作成して作業中のドメイン固有のタスクを実行でき、ユーザーは定義された演算子を使用して通常のような問合せを構成できます。

拡張可能索引付けを使用する場合

Oracleの組込み索引付け機能は、様々な状況に適しています。ただし、データが複雑になり、アプリケーションが特定のドメインにあわせて調整されると、他のアプローチを必要とする状況が生じてきます。たとえば、拡張可能索引付けは次のような問題の解決に役立ちます。

  • 特化された索引構造を使用した新規の検索演算子の実装

    演算子を定義し、索引構造を使用して特化された検索を実行できます。

  • 構造化されていないデータの索引付け

    組込み機能では、LOB値を含む列の索引付けはできません。

  • 列オブジェクトの属性の索引付け

    組込み機能では、列オブジェクトまたはコレクション型の要素の索引付けはできません。

  • ドメイン固有の操作から導出された値の索引付け

    Oracleオブジェクト型は、マップ・ファンクションまたは順序付けファンクションに匹敵します。オブジェクトでマップ・ファンクションが使用される場合は、関係述語の評価に使用するファンクション索引を定義できます。ただし、これが機能するのは有限範囲のパラメータを持つ述語の場合のみで、すべての行のファンクション値を事前計算できる必要があります。また、順序付けファンクションを使用して索引を構成することはできません。

索引構造

この項では、使用頻度の高い索引構造を紹介し、ドメイン索引の設計者に使用可能な選択肢を示します。

Bツリー

あらゆるニーズを満たす索引構造は存在しませんが、自己均衡型のBツリー索引は大きいデータ・セットの検索パフォーマンスの最適化に最も適しています。各Bツリー・ノードには、複数のキーとポインタが保持されます。特定のBツリーでサポートされている1ノードの最大キー数は、そのツリーの階数です。各ノードは、下位レベルへの階数1個のポインタを持つ可能性があります。たとえば、図7-1に示す階数=2のBツリーにはツリー・ポインタがあり、それぞれ値が第1キーより小さい子ノード、値が第1キーより大きく第2キーより小さい子ノード、値が第2キーより大きい子ノードを指します。つまり、Bツリー・アルゴリズムは、決定ノードごとにキーが1つと子が最大2つしかないバイナリ・ツリー・アルゴリズムよりも少数のノードを通過することで、レコードの検索に必要な読み書き数を最小限に抑えます。ここでは、Knuthバリエーションについて説明します。この場合、索引は2つの部分で構成され、一方はデータへの高速逐次アクセスを提供する順序セットで、他方は順序セットへのダイレクト・アクセスを提供する索引セットです。

通常、Bツリーのノードに同数のデータ値が含まれることはなく、使用されない領域が一定量含まれていますが、Bツリー・アルゴリズムではツリーのバランスが常にとれていることと、リーフ・ノードが同じレベルにあることが保証されます。

図7-1 Bツリー索引構造

図7-1の説明は次にあります。
「図7-1 Bツリー索引構造」の説明

ハッシュ

ハッシングは、特定のフィールド値に基づいて特定のストアド・レコードへの高速ダイレクト・アクセスを提供します。各レコードの格納位置のアドレスは、そのレコードのなんらかのフィールドのなんらかのファンクションとして計算されます。同じファンクションが挿入と取出しに使用されます。

ハッシングには、論理的な順序付けに関連する場合、レコードの物理的な順序付けが小さいという問題があります。また、ディスク上の未使用領域が大きくなる場合があります。

表7-2 ハッシュ索引構造

図7-2の説明は次にあります。
「図7-2 ハッシュ索引構造」の説明

k-dツリー

緯度と経度のような2つのディメンションを持つデータは、2-dツリーと呼ばれるk-dツリーのバリエーションを使用すると効率的に格納し、取り出すことができます。

この構造では、各ノードは情報フィールド、2つの座標、2つの子を指す左リンクと右リンクを持つデータ型です。

図7-3 2-d索引構造

図7-3の説明は次にあります。
「図7-3 2-d索引構造」の説明

この構造は、範囲問合せに適しています。つまり、ユーザーが点(xx, xx)と距離を指定すると、問合せでは原点から指定した距離の範囲内にあるすべての点のセットが戻されます。

2-dツリーは実装が容易です。ただし、k個のノードを含む2-dツリーの高さはkになることがあるため、挿入および問合せが複雑になる可能性があります。

点quadtree

図7-4のように、点quadtreeも2次元空間における点データの表現に使用されますが、2-dツリーではリージョンが2つにわかれているのに対して、この種の構造ではリージョンが4つにわかれています。このノードのレコード・タイプのフィールドは、情報の属性、2つの座標および4つの子を指す4つの方位点(NW、SW、NE、SEなど)で構成されています。

図7-4 点quadtree索引構造

図7-4の説明は次にあります。
「図7-4 点quadtree索引構造」の説明

2-dツリーと同様に、点quadtreeは実装が容易です。ただし、k個のノードを含む点quadtreeの高さはkになることがあるため、挿入および問合せが複雑になる可能性があります。それぞれを比較するには、少なくとも2つの座標での比較が必要です。ただし、実際には点quadtreeの方がルートからリーフまでの長さが短くなる傾向があります。

拡張可能索引付け

拡張可能索引付けフレームワークは、ドメイン固有の演算子と索引付け方法を定義してOracleサーバーに統合できるSQLベースのインタフェースです。

拡張可能索引付けフレームワークは、次のコンポーネントで構成されています。

拡張可能索引付けフレームワークを使用すると、次のことができます。

拡張可能索引付けフレームワークを使用すると、他のOracle索引と同様に動作するドメイン索引を作成できます。ユーザーは、定義された演算子を使用して標準的な問合せを記述します。ドメイン索引の作成、削除、切捨て、変更および検索を行うために、索引タイプの一部として指定したアプリケーション・コードがOracleサーバーにより起動されます。

Text索引タイプの使用

この項では、拡張可能な索引付けフレームワークについて説明します。例として、Text索引タイプを使用して新規のテキスト索引付け方法を定義する概略例およびText索引タイプを使用して、テキスト・データに索引付けおよび操作する概略例を示します。

索引タイプの定義

索引タイプのコンポーネントの作成順序は、索引ベースのファンクション実装を作成するかどうかに応じて異なります。

索引ベースでないファンクション実装

索引タイプ設計者がText索引タイプを定義する手順は、次のとおりです。

  1. サポートされている演算子のファンクション実装を定義してコーディングします。

    Text索引タイプでは、演算子Containsがサポートされます。この演算子はテキスト値とキーを受け入れて、テキストにキーが含まれているかどうかを示す数値を戻します。この演算子のファンクション実装は、次のように定義された標準ファンクションです。

    CREATE FUNCTION TextContains(Text IN VARCHAR2, Key IN VARCHAR2)
    RETURN NUMBER AS
    BEGIN
    .......
    END TextContains;
    
  2. 新規の演算子を作成してファンクション実装にバインドします。

    CREATE OPERATOR Contains
     BINDING (VARCHAR2, VARCHAR2) RETURN NUMBER USING TextContains;
    
  3. 索引インタフェースODCIIndexを実装するタイプを定義します。

    そのためには、索引定義、索引メンテナンスおよび索引スキャンの各操作用のルーチンを実装する必要があります。Oracleは、次のルーチンをコールします。

    CREATE TYPE TextIndexMethods
    (
    STATIC FUNCTION ODCIIndexCreate(...)
    ...
    );
    CREATE TYPE BODY TextIndexMethods
    (
    ...
    );
    
  4. Text索引タイプのスキーマ・オブジェクトを作成します。

    索引タイプ定義では、新規の索引タイプでサポートされる演算子と、索引インタフェースを実装するタイプを指定します。

    CREATE INDEXTYPE TextIndexType
    FOR Contains(VARCHAR2, VARCHAR2)
    USING TextIndexMethods
    WITH SYSTEM MANAGED STORAGE TABLES;
    

索引ベースのファンクション実装

索引ベースのファンクション実装を作成する場合に実行する操作は、索引ベースでないファンクション実装の場合と同じですが、操作の順序が異なります。

  1. 実装タイプの定義

  2. ファンクション実装の定義とコーディング

  3. 演算子の作成

  4. 索引タイプの作成

この順序が必要なのは、索引ベースのファンクション実装の定義には、パラメータとして実装タイプが必要となるためです。

索引タイプの使用

前項に示したText索引タイプが定義されている場合、ユーザーはテキスト列にテキスト索引を定義し、Contains演算子を使用してテキスト・データを問い合せることができます。

Employees表が次の文で定義されているとします。

CREATE TABLE Employees
(name VARCHAR2(64), id INTEGER, resume VARCHAR2(2000));

resume列にテキスト・ドメイン索引を作成するには、次の文を発行します。

CREATE INDEX ResumeIndex ON Employees(resume) INDEXTYPE IS TextIndexType;

resume列のテキスト・データを問い合せるには、次のような文を発行します。

SELECT * FROM Employees WHERE Contains(resume, 'Oracle') =1;

問合せの実行では、resumeのテキスト索引を使用してContains条件が評価されます。