CREATE INDEX
ストアに索引定義を追加するには、CREATE INDEX
文を使用します。これを使用して、単純な索引および複数キー索引を作成できます。JSON索引の作成にも使用できます。
索引付けが可能なフィールドの型
フィールドは次のいずれかの型になるように宣言されている場合のみ索引付けが可能です。すべての複合型(配列、マップおよびレコード)では、索引の最終ターゲットがスカラー・データ型の場合のみフィールドが索引付け可能です。つまり、ネストされた複合型(レコードの配列など)を含む複合型では、索引のターゲットが埋込みレコードに含まれるスカラー・データ型の場合に索引付けが可能です。
-
整数
-
ロング
-
数値
-
浮動小数
-
倍精度
-
Json
Jsonデータの索引付けと他のデータ型の索引付けには、いくつかの相違点と制限事項があります。詳細は、JSON索引を参照してください。
-
文字列
-
列挙
-
配列
配列の場合、配列に別の索引付けが可能なスカラー型の1つである値が含まれる場合のみ、フィールドは索引付けが可能です。たとえば、整数の配列には索引を作成できます。レコードの配列にある特定のレコードにも索引を作成できます。配列エントリごとに索引エントリがあると、索引のサイズが急激に増加してしまうため、1つの索引には1つの配列のみが加えられます。
-
マップ
配列の場合と同様に、マップにスカラー型がある場合、またはマップにスカラー型を含んだレコードがある場合には、マップに索引付けできます。
-
レコード
配列およびマップと同様に、フィールドにスカラー・データが含まれている場合には、埋込みレコードのフィールドに索引付けが可能です。
単純索引
マップまたは配列を索引付けしない場合、索引は単純です。単純索引を作成するには、次のように実行します。
CREATE INDEX [IF NOT EXISTS] index-name ON table-name (path_list)
説明:
-
IF NOT EXISTS
はオプションで、これによりその名前の索引がすでに存在している場合にはCREATE INDEX
文は無視されます。このフレーズが指定されずに、指定した名前を使用している索引が現在存在している場合には、CREATE INDEX
文はエラーで失敗します。 -
index-nameは作成する索引の名前です。
-
table-nameは索引付けする表の名前です。
-
path_listは、1つ以上のname_pathsのカンマ区切りリストです。name_pathは、表の要素を参照します。通常はスキーマ・フィールド、つまり、関連表の作成に使用されるCREATE TABLE式に示されるフィールド名です。
ただし、表にレコードが含まれている場合、name_pathはレコード・フィールドを識別するためにドット表記法を使用したレコード・キーである可能性があります。次に例を示します。
CREATE TABLE example ( id INTEGER, myRecord RECORD(field_one STRING, field_two STRING), PRIMARY KEY (id) )
その後、
myRecord.field_one
のname_pathを使用して、field_oneに索引を作成できます。レコードの索引付けの詳細は、埋込みレコードの索引付けを参照してください。
たとえば、表Users
にlastName
という名前のフィールドがある場合、そのフィールドを次の文で索引付けできます。
CREATE INDEX surnameIndex ON Users (lastName)
ストア内のデータ量によっては、索引の作成に時間がかかる可能性があることに注意してください。これは、索引の作成ではOracle NoSQL Databaseがストア内のすべてのデータを調べる必要があるからです。
複数キー索引
複数キー索引は、配列のすべての要素の索引付けに使用されます。マップのすべての要素や値の索引付けにも使用されます。
表の各行に対して、複数キー索引には、索引付けされる配列/マップの要素/エントリと同じ数のエントリが含まれます(ただし、重複エントリは索引内に示されません)。索引エントリの数の急増を回避するには、1つの配列/マップのみを単一の複数キー索引に含めることができます。
複数キー索引を作成するには、次のいずれかの形式を使用します。
CREATE INDEX [IF NOT EXISTS] index-name ON table-name (name-path.keys())
または
CREATE INDEX [IF NOT EXISTS] index-name ON table-name (name-path.values())
または
CREATE INDEX [IF NOT EXISTS] index-name ON table-name \
(name-path.keys(),name-path.values())
または
CREATE INDEX [IF NOT EXISTS] index-name ON table-name (name-path[])
前述の構文は、単純索引で説明した構文と同じですが、次のものが追加されています。
-
.keys()
索引は、マップのキーに対して作成されます。使用する場合、name-pathはマップである必要があります。
-
.values()
索引は、マップの値に対して作成されます。使用する場合、name-pathはマップである必要があります。
-
[]
索引は、配列に対して作成されます。使用する場合、name-pathは配列である必要があります。
これまでに示した各形式では、name-pathsのカンマ区切りリストを指定できます。いくつかの制限が適用されます。
複数キー索引の制限
複数キー索引には、次の制限が適用されます。
-
複数キーのステップ(
.keys()
、.values()
または[]
)を使用するname-pathが少なくとも1つ存在します。そのようなパスは複数キー・パスと呼ばれ、関連する索引フィールドは複数キー・フィールドと呼ばれます。索引定義には複数の複数キー・パスが含まれる場合がありますが、すべての複数キー・パスで複数キー・ステップの前に同じname-pathを使用する必要があります。 -
複数キー以外のパスは単純パスにする必要があります。
-
索引用に指定した結合パスには、少なくとも1つのマップまたは配列(あるいはその両方)が含まれている必要があります。これらには、索引付け可能なアトミック項目、レコード項目またはマップ項目が含まれている必要があります。つまり、一連の配列の索引はサポートされておらず、配列を含むマップの索引もサポートされていません。
たとえば、次のような表定義があるとします。
create table Foo ( id INTEGER, complex1 RECORD(mapField MAP(ARRAY(MAP(INTEGER)))), complex2 RECORD(matrix ARRAY(ARRAY(RECORD(a LONG, b LONG))) primary key(id) )
パス式
complex2.matrix[]
は有効ではありません。これは、このパス式の結果がアトミック項目ではなく一連の配列であるためです。complex2.matrix[][].a
は、他の配列内の配列に索引付けできないため、有効ではありません(実際、このパスでは、構文上1つの索引パスにつき最大1つの[]
しか使用できないため、構文エラーが発生します)。一方、パス
complex1.mapField.someKey[].someOtherKey
は有効です。この場合、パスcomplex1.mapField.someKey
はマップを含む配列を指定しており、これは有効です。この索引パスでは、someKey
およびsomeOtherKey
はマップエントリ・キーです。そのため、マップ内に含まれる配列に索引付けし、索引付けする配列にマップが含まれますが、パスは有効です。これは、すべての配列エントリに加えて、すべてのマップ・エントリに索引付けするのではなく、マップの特定のエントリを選択しているためです。 -
索引で配列値フィールドを索引付けする場合:
-
配列に索引付け可能なアトミック項目が含まれる場合:
-
M[]
形式の単一の複数キー索引パスが必要です([]の後にname_pathを続けない)。この場合も、同じ索引内で複数の配列を索引付けできないことを意味します。 -
表の行(R)ごとに、次のように多数の索引エントリが作成されます。
単純索引パス(ある場合)はRで計算されます。
この場合、M[]が(問合せパス式である場合と同様に)計算され、NULLまたはEMPTY、あるいはMによって返された配列のすべての要素が返されます。
最後に、M[]によって返された各値(V)について、フィールド値がVおよび単純パスの値である索引エントリが作成されます。
-
前述のプロセスで作成される重複索引エントリ(等しいフィールド値および同じ主キーを持つ)は消去されます。
-
-
配列にレコードまたはマップが含まれる場合:
-
すべての複数キー・パスは、
M[].name_path
の形式にする必要があります。複数キー索引パスのM[]の後に表示される各name_pathは、索引付けが可能なアトミック項目を最大で1つ返す必要があります。 -
表の行(R)ごとに、次のように多数の索引エントリが作成されます。
単純索引パス(ある場合)はRで計算されます。
この場合、M[]が(問合せパス式である場合と同様に)計算され、NULLまたはEMPTY、あるいはMによって返された配列のすべての要素が返されます。
次に、M[]によって返された値(V)ごとに、次のように1つの索引エントリが作成されます。
各Vに含まれる要素が計算されます。これにより、単一の索引付けが可能なアトミック項目(NULLまたはEMPTY項目の場合もあります)が返されます。これらのそれぞれに索引エントリが作成され、そのフィールド値は、単純索引パスの値に、Vに含まれている要素について見つかった値を加えた値です。
-
前述のプロセスで作成される重複索引エントリ(等しいフィールド値および同じ主キーを持つ)は消去されます。
-
-
索引でマップ値フィールドに索引付けする場合、索引により、マップ・キーのみ、マップ要素のみまたはキーと要素の両方に索引付けされることがあります。いずれの場合も、マップ索引の定義は配列索引の観点で指定できます。そのためには、2つのフィールドを持つレコードを含む配列としてマップを表示します。1つは"key"という名前で値がマップ・キーであるフィールド、もう1つは"element"という名前で値が対応するマップ要素であるフィールドです(つまり、MAP(T)はARRAY(RECORD(key STRING, element T))として表示されます)。次に、マップ索引で有効な2種類は次のとおりです。
-
keys()のステップを使用した単一の複数キー索引パス。マップの配列ビューを使用する場合、M.keys()はM[].keyに相当します。
-
.values()ステップを使用する1つ以上の複数キー索引パス。Riがマップに含まれる値である場合、それぞれの形式はM.values().Riになります。マップの配列ビューを使用する場合、各M.values().RiパスはM[].element.Riに相当します。
-
-
JSON索引
索引がJSON索引であるのは、JSONデータ内に含まれるフィールドを少なくとも1つ索引付けする場合です。
JSONはスキーマレスであるため、表の行全体でJSONデータの型が異なる場合があります。ただし、JSONデータを索引付けするときには、データ型が表の行全体で一貫している必要があります。そうでない場合、索引の作成は失敗します。さらに、1つ以上のJSON索引が作成された場合、正しくない型のデータを書き込もうとすると失敗します。
JSONデータの索引付けとJSON索引の操作は、JSON以外のデータの索引付けとほぼ同じ方法で実行されます。索引を作成するには、ドット表記法を使用してJSONフィールドへのパスを指定します。
JSON索引を作成するときは、AS
キーワードを使用して、データの型を指定する必要があります。データ型はアトミックである必要があり、浮動小数にすることはできません。つまり、JSON索引では、整数、ロング、倍精度、数値、文字列およびブール型のみがサポートされています。配列およびマップは、これらのアトミック値が含まれるかぎり、索引付けすることができます。
CREATE INDEX [IF NOT EXISTS] index-name ON table-name \
(JSONRow.JSONField AS data_type)
JSONマップに複数キー索引を作成するときは、型が常にString
になるため、.keys()
式に型を指定しないでください。ただし、.values()
式には型宣言が必要です。さらに、複数キー索引の制限で説明したすべての制約が、JSON複数キー索引にも適用されます。
CREATE INDEX [IF NOT EXISTS] index-name ON table-name \
(JSONRow.JSONField.keys(),\
JSONRow.JSONField.values() AS data_type)