索引の分類
索引は、フィールド、スキーマ、エントリまたはそれらの組合せに基づいて分類できます。次に、それぞれについて説明します。
- フィールド
- 単一フィールド索引
- コンポジット索引
- スキーマ
- 固定スキーマ索引
- スキーマレス索引(JSON索引)
- エントリ
- 単純索引
- 複数キー索引
- 固定スキーマ索引
- 索引は、索引付けされるすべてのフィールドが強く型指定されたデータである場合、固定スキーマ索引と呼ばれます。強い型指定のデータの詳細は、「ワイルドカード・データ型」の項を参照してください。
- スキーマレス索引(JSON索引)
- 索引は、少なくとも1つのフィールドがJSONデータまたはJSONデータ内のフィールドである場合、JSON索引と呼ばれます。
図8-1 索引分類

単一フィールド索引
索引は、表の1つのフィールドにのみ作成される場合、単一フィールド索引と呼ばれます。
例8-2 単一フィールド索引
次に、単一フィールド索引の例を示します。索引は、UserInfo
表のinfo
JSONフィールドのaddress
レコードに存在するcity
フィールドに作成されます。
CREATE INDEX singlefieldindex1 ON UserInfo (
info.address.city AS ANYATOMIC
);
コンポジット索引
索引は、表の複数のフィールドに作成されている場合、コンポジット索引と呼ばれます。
例8-3 コンポジット索引
次に、コンポジット索引の例を示します。索引は、UserInfo
表のinfo
JSONフィールドのaddress
レコードに存在するstate
およびcity
フィールドに作成されます。
CREATE INDEX compositeindex1 ON UserInfo (
info.address.state AS ANYATOMIC,
info.address.city AS ANYATOMIC
);
固定スキーマ索引
固定スキーマ・データを持つフィールドに索引を作成できます。
例8-4 固定スキーマ索引
次に、固定スキーマ索引の例を示します。索引は、UsersInfo
表の整数データ型を持つuname
フィールドに作成されます。
CREATE INDEX fixedschemaindex1 ON UserInfo (uname);
JSON索引
索引は、少なくとも1つのフィールドがJSONデータ内にある場合、JSON索引と呼ばれます。
JSONはスキーマレスであるため、索引付けされたJSONフィールドのデータ型は行間で異なることがあります。JSONフィールドに索引を作成するときに、JSONフィールドに必要なデータ型が不明な場合は、anyAtomicデータ型を使用できます。または、Oracle NoSQL Databaseアトミック・データ型のいずれかを指定できます。これを行うには、JSONフィールドへのすべての索引パスの横でASキーワードを使用してデータ型を宣言します。
例8-5 JSON索引
次に、JSON索引の例を示します。索引は、UserInfo
表のinfo
JSONフィールドに存在するincome
フィールドに作成されます。索引の作成時にincome
フィールドのデータ型を指定します。
CREATE INDEX jsonindex1 ON UserInfo (
info.income AS INTEGER
);
宣言されたデータ型に違反するデータを持つ行が関連表に含まれている場合、JSON索引の作成は失敗します。同様に、JSON索引の作成後、新しい行がJSON索引で宣言されたデータ型に準拠していない場合、挿入/更新操作は失敗します。
たとえば、jsonindex1
索引は、UserInfo
表のすべての行のincome
フィールドが整数データ型の場合にのみ作成され、それ以外の場合はjsonindex1
索引の作成は失敗します。同様に、UserInfo
表にjsonindex1
索引を作成した後は、income
フィールドが整数データ型の行のみを挿入できます。たとえば、income
フィールドが文字列データ型の行を挿入しようとすると、挿入文は失敗します。
- 数値
- 文字列
- ブール
ただし、この利点は領域およびCPUコストによって相殺されます。これは、索引付きフィールドの任意の種類の数値が、索引に格納される前に数値にキャストされるためです。このキャストにはCPU時間がかかり、結果として得られる数値の記憶域は、元の数値の記憶域より大きくなります。
例8-6 JSON索引の例
次に、JSON索引の例を示します。索引は、UserInfo
表のinfo
JSONドキュメントのaddress
フィールドに存在するstreet
フィールドに作成されます。索引の作成時にstreet
フィールドにanyAtomicデータ型を指定することに注意してください。
CREATE INDEX jsonindex2 ON UserInfo (
info.address.street AS ANYATOMIC
);
単純索引
索引は、表のデータ行ごとに1つのエントリが索引に作成される場合、単純索引と呼ばれます。索引は、アトミック・データ型の単一の値または任意の特別な値(SQL NULL、JSON NULL、EMPTY)を返します。基本的に、単純索引の索引パスには、.keys()
、.values()
または[]
ステップを含めないでください。
例8-7 単純索引
次に、単純索引の例を示します。索引は、UserInfo
表のinfo
JSONフィールドに存在するincome
およびage
フィールドに作成されます。
CREATE INDEX simpleindex1 ON UserInfo (
info.income AS ANYATOMIC,
info.age AS ANYATOMIC
);
配列は複数の索引値をレンダリングするため、単純な索引パスに配列を含めることはできません。たとえば、info.connections[]
は、info.connections
配列内の要素の完全なセットを返します。これは単純索引ではありません。
同様に、単純な索引パスには、.keys()
または.values()
を含むマップを含めないでください。たとえば、info.expenses.keys()
は、expenses
マップ内のキーの完全なセットを返します。これは単純な索引パスではありません。ただし、info.expenses.books
は単純な索引パスです。info.expenses
がマップであっても、info.expenses.books
はアトミック値を返すためです。
例8-8 単純索引の例
次に、JSONフィールドのJSONドキュメントに作成される単純索引の例を示します。索引は、UserInfo
表のinfo
JSONフィールドにあるexpenses
JSONドキュメントのbooks
項目に作成されます。
CREATE INDEX simpleindex2 ON UserInfo (
info.expenses.books AS ANYATOMIC
);
単純な索引パスの評価で空の結果が返された場合、特別な値EMPTYが索引エントリとして使用されます。前述の例では、expenses
JSONドキュメントにbooks
エントリがない場合、またはexpenses
JSONドキュメントがない場合、特別な値EMPTYが索引付けされます。
複数キー索引
索引は、表のデータ行ごとに索引に複数のエントリが作成される場合、複数キー索引と呼ばれます。複数キー索引には、.keys()
、.values()
または[]
ステップを使用する索引パスが少なくとも1つあります。このような索引パスはすべて、複数キー索引パスと呼ばれます。
複数キー索引では、表の行ごとに、索引付けされるマップ内の配列またはエントリのすべての要素に索引エントリが作成されます。評価で空の結果が返された場合は、特別な値EMPTYが索引エントリとして使用されます。重複する索引エントリは削除されます。
例8-9 複数キー索引
次に、複数キー索引の例を示します。索引は、UserInfo
表のconnections[]
配列に作成されます。ここでは、UserInfo
表の各行のconnections[]
配列のすべての要素が索引付けされます。
CREATE INDEX multikeyindex1 ON UserInfo (
info.connections[] AS ANYATOMIC
);
ネストされた複数キー索引
索引は、別の配列内に存在する配列内に存在するフィールドに作成される場合、ネストされた複数キー索引です。
例8-10 ネストされた複数キー索引
次に、別の配列内に存在する配列にフィールドが存在する、ネストされた複数キー索引の例を示します。索引は、UserInfo
表のinfo
JSONにあるvehicles
配列のvpass
配列のissuedby
フィールドに作成されます。
CREATE INDEX multikeyindex2 ON UserInfo (
info.vehicles[].vpass[].issuedby AS ANYATOMIC
);
コンポジット複数キー索引
索引は、索引が複数のフィールドに作成され、それらのフィールドの少なくとも1つが複数キーである場合、コンポジット複数キー索引と呼ばれます。
コンポジット複数キー索引には、複数キー索引パスと単純索引パスの組合せを使用できます。
例8-11 コンポジット複数キー索引
次に、1つの複数キー索引パスと1つの単純索引パスを持つコンポジット複数キー索引の例を示します。索引は、UserInfo
表のinfo
JSON列のincome
フィールドおよびarea
フィールドに作成されます。
CREATE INDEX multikeyindex3 ON UserInfo (
info.income AS ANYATOMIC,
info.address.phones[].area AS ANYATOMIC
);
コンポジット複数キー索引には、複数の複数キー索引パスを指定できます。コンポジット複数キー索引の可能性をいくつか、次に示します。
-
マップまたはJSONの
.keys()
ステップと.values()
ステップの両方を一緒に使用できます。次に、JSONドキュメントの
.keys()
ステップと.values()
ステップの両方が一緒に使用されるコンポジット複数キー索引の例を示します。索引は、UserInfo
表のexpenses
JSONドキュメントのkeys
およびvalues
に作成されます。CREATE INDEX multikeyindex4 ON UserInfo ( info.expenses.keys(), info.expenses.values() as ANYATOMIC );
-
array/record/maps-viewed-as-recordsの複数のフィールドを一緒に使用できます。ただし、ここでの制限は、フィールドを単一の
CREATE INDEX
文内で配列とマップの両方として処理できないことです。次に、配列の複数のフィールドが一緒に使用されるコンポジット複数キー索引の例を示します。索引は、
UserInfo
表のvpass
配列のpassid
およびissuedby
フィールドに作成されます。CREATE INDEX nestedindex1 ON UserInfo ( info.vehicles[].vpass[].passid AS ANYATOMIC, info.vehicles[].vpass[].issuedby AS ANYATOMIC );
図8-2 コンポジット複数キー索引
-
array/record/maps-viewed-as-recordsのフィールドと、それらのarray/record/maps-viewed-as-recordsの内部配列内に存在するフィールドを一緒に使用できます。ただし、ここでの制限は、そのようなすべてのフィールドの直属の親配列が同じである必要があることです。
次に、配列のフィールドと内部配列のフィールドが一緒に使用されるコンポジット複数キー索引の例を示します。索引は、
vehicles
配列のvid
フィールドおよびUserInfo
表のvehicles
配列にあるvpass
配列のpassid
フィールドに作成されます。CREATE INDEX nestedindex2 ON UserInfo ( info.vehicles[].vid AS ANYATOMIC, info.vehicles[].vpass[].passid AS ANYATOMIC );
図8-3 コンポジット複数キー索引
次に、配列のフィールドと内部配列のフィールドが一緒に使用されるコンポジット複数キー索引の例を示しますが、2つのフィールドの直属の親配列は同じではありません。無効な索引作成文を次に示します。索引は、UserInfo
表のvehicles
配列のpassid
およびserviceid
フィールドに作成されます。vehicles
配列内では、passid
はvpass
配列内にあり、serviceid
はvservice
配列内にあることに注意してください。
CREATE INDEX invalidindex1 ON UserInfo (
info.vehicles[].vpass[].passid AS ANYATOMIC,
info.vehicles[].vservice[].serviceid AS ANYATOMIC
);
図8-4 コンポジット複数キー索引(無効)

複数キー索引の仕様および制限
次の仕様および制限が複数キー索引パスに適用されます。
.keys()
、.values()
および[]
ステップには述語式または境界式を指定できません。述語式および境界式の詳細は、それぞれ「マップフィルタ・ステップ式」および「配列スライス・ステップ式」の項を参照してください。- 複数キー索引パスが表の行で評価される場合、ゼロ以上のアトミック値を返す必要があります。値が返されない場合、特別な値EMPTYが使用されます。
keys()
はデフォルトの文字列データ型であるため、.keys()
ステップではデータ型の宣言は許可されません。.keys()
ステップは、索引パスの最後のステップとしてのみ指定できます。- たとえば、
info.expenses.keys()
は有効な索引パスですが、info.expenses.keys().books
は無効な索引パスです。 .keys()
および.values()
は、強い型指定のデータのマップであるフィールドの後にのみ指定できます。.keys()
および.values()
ステップは、アトミック値またはJSONデータ内のJSONドキュメントであることが予想されるフィールドの後に指定できます。- フィールドがアトミック値の場合は、特別な値EMPTYが返されます。
- フィールドがjsonドキュメントの場合は、対応するキーまたは値が返されます。
- 強い型指定のデータの配列であるフィールドの後に、
[]
ステップを指定する必要があります。 - JSONデータ内の配列であることが予想されるフィールドの後に、
[]
ステップを指定する必要があります。 - JSONデータ内の配列であることが予想されるフィールドの後に
[]
ステップを指定しない場合、それらのフィールドは配列にできません。- 既存の表の行にJSONデータ内の配列が含まれている場合、索引の作成は失敗します。
- ただし、JSONデータ内の配列が含まれている既存の表に行がない場合、索引は正常に作成されます。ただし、そのJSONデータの配列を含む新しい行を既存の表に挿入することはできません。
- たとえば、次の
badindex1
では、[]
ステップはvehicles
配列では使用されません。2つのシナリオがあります:CREATE INDEX badindex1 ON UserInfo(info.vehicles.vid AS ANYATOMIC);
vehicles
フィールドが配列であるUserInfo
表に既存のデータ行がある場合、索引の作成は失敗します。UserInfo
表にvehicles
配列を持つ既存のデータ行がない場合、索引は正常に作成されます。ただし、vehicles
属性が配列であるデータの新しい行を挿入しようとすると、行の挿入は失敗します。
- 強い型指定のデータの非配列フィールドの後に
[]
ステップを指定できません。 - JSONデータのアトミック値およびJSONドキュメントの後に
[]
ステップを指定できます。その場合、そのアトミック値またはJSONドキュメントが使用されます。 - 配列に別の配列が直接含まれている場合、内部配列の要素を索引付けするには、対応する数の
[]
ステップが必要です。たとえば、vehicles
内に2つの内部配列がある場合は、info.vehicles[][].vid
を使用する必要があります。