索引の作成

索引付けが可能なフィールド・タイプ

索引は、表の行を取得する代替方法を表します。通常は、行の主キーを使用して表の行を取得します。索引を作成することで、主キー値が異なるが、他の特性を共有する行を取得できます。

索引は、主キー・フィールドを含め、索引付けが可能なデータ型のすべてのフィールドに作成できます。索引付けが可能なフィールドの型の詳細は「索引付けが可能なフィールドの型」を参照してください。

たとえば、自動車のタイプを表す表がある場合、各行の主キーは自動車の製造業者およびモデル・タイプになります。ただし、製造業者またはモデル・タイプに関係なく、赤く塗装されたすべての自動車を問い合せることができるようにするには、色情報を含む表のフィールドに索引を作成します。

Oracle NoSQL Databaseはストアの関連表に含まれるすべてのデータを調べる必要があるため、索引の作成には時間がかかる場合があります。表に含まれるデータが小さいほど、索引の作成が高速になります。逆に、表に多数のデータが含まれる場合、索引の作成には時間がかかる可能性があります。

CREATE TABLE myInventory.itemDetails (
    itemSKU STRING,
    itemDescription STRING,
    price FLOAT,
    inventoryCount INTEGER,
    PRIMARY KEY (itemSKU)
) 

索引を作成するには、CREATE INDEX文を使用します。詳細は、「CREATE INDEX」を参照してください。次に例を示します。

CREATE INDEX inventoryIdx on myInventory.itemDetails(inventoryCount)

同様に、索引を削除するには、DROP INDEX文を使用します。詳細は、「DROP INDEX」を参照してください。

DROP INDEX inventoryIdx on myInventory.itemDetails

索引の追加および削除には時間がかかる可能性があることに注意してください。そのため、TableAPI.execute()メソッドを使用して、これらの操作を非同期に実行することもできます。

package kvstore.basicExample;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import oracle.kv.FaultException;
import oracle.kv.KVStore;
import oracle.kv.KVStoreConfig;
import oracle.kv.KVStoreFactory;
import oracle.kv.table.ExecutionFuture;
import oracle.kv.table.StatementResult;
import oracle.kv.table.TableAPI;

...
// Store open skipped
... 

public void createIndex() {
    TableAPI tableAPI = store.getTableAPI();
    ExecutionFuture future = null;
    StatementResult result = null;
    String statement = null;

    try {

        statement = "CREATE INDEX inventoryIdx on " +
                    "myInventory.itemDetails(inventoryCount)"
        future = tableAPI.execute(statement);
        displayResult(future.getLastStatus(), statement);

        /*
         * Limit the amount of time to wait for the
         * operation to finish.
         */
        result = future.get(3, TimeUnit.SECONDS);
        displayResult(result, statement);

    } catch (IllegalArgumentException e) {
        System.out.println("Invalid statement:\n" + e.getMessage());
    } catch (FaultException e) {
        System.out.println
            ("Statement couldn't be executed, please retry: " + e);
        cleanupOperation(future);
    } catch (ExecutionException e) {
        System.out.println
            ("Problem detected while waiting for a DDL statement: " +
             e.getCause());
        cleanupOperation(future);
    } catch (InterruptedException e) {
        System.out.println
            ("Interrupted while waiting for a DDL statement: " + e);
        cleanupOperation(future);
    } catch (TimeoutException e) {
        System.out.println("Statement execution took too long: " + e);
        cleanupOperation(future);
    }
}

private void cleanupOperation(ExecutionFuture future) {
    if (future == null) {
        /* nothing to do */
        return;
    }

    System.out.println("Statement:");
    System.out.println(future.getStatement());
    System.out.println("has status: ");
    System.out.println(future.getLastStatus());

    if (!future.isDone()) {
        future.cancel(true);
        System.out.println("Statement is cancelled");
    }
}

private void displayResult(StatementResult result, String statement) {
    System.out.println("===========================");
    if (result.isSuccessful()) {
        System.out.println("Statement was successful:\n\t" + 
                            statement);
        System.out.println("Results:\n\t" + result.getInfo());
    } else if (result.isCancelled()) {
        System.out.println("Statement was cancelled:\n\t" + 
                            statement);
    } else {
        /*
         * statement wasn't successful: may be in error, or may still be
         * in progress.
         */
        if (result.isDone()) {
            System.out.println("Statement failed:\n\t" + statement);
            System.out.println("Problem:\n\t" + result.getErrorMessage());
        } else {
            System.out.println("Statement in progress:\n\t" + statement);
            System.out.println("Status:\n\t" + result.getInfo());
        }
    }
} 

索引付けが可能なフィールドの型

フィールドは次のいずれかの型になるように宣言されている場合のみ索引付けが可能です。すべての複合型(配列、マップおよびレコード)では、索引の最終ターゲットがスカラー・データ型の場合のみフィールドが索引付け可能です。つまり、ネストされた複合型(レコードの配列など)を含む複合型では、索引のターゲットが埋込みレコードに含まれるスカラー・データ型の場合に索引付けが可能です。

  • Integer

  • Long

  • Float

  • Double

  • String

  • Enum

  • Array

    配列の場合、配列に別の索引付けが可能なスカラー型の1つである値が含まれる場合のみ、フィールドは索引付けが可能です。たとえば、整数の配列には索引を作成できます。レコードの配列にある特定のレコードにも索引を作成できます。配列エントリごとに索引エントリがあると、索引のサイズが急激に増加してしまうため、1つの索引には1つの配列のみが加えられます。

  • Map

    配列の場合と同様に、マップにスカラー型がある場合、またはマップにスカラー型を含んだレコードがある場合には、マップに索引付けできます。

  • Record

    配列およびマップと同様に、フィールドにスカラー・データが含まれている場合には、埋込みレコードのフィールドに索引付けが可能です。

サポートされている非スカラー型に索引付けする例は、「非スカラー・データ型の索引付け」を参照してください。