6 JSONコレクション
JSONコレクションは、一連のJSON文書を格納または提供するデータベース・オブジェクトです。クライアント・アプリケーションは通常、ドキュメントAPIによって提供される操作を使用して、コレクションとその文書を操作します。SQLを使用して操作することもできます。
Oracle Databaseでは、JSONコレクションは、DATA
という名前の単一のJSON
型のオブジェクト列にJSON文書を提供する特別な表またはビューです。
JSONコレクションの表またはJSONリレーショナル二面性ビュー内の各ドキュメントには、最上位に値がコレクションに対して一意であるdocument-identifierフィールド、_id
が必要です。脚注1 コレクションにすでに存在するドキュメントと同じ_id
値を持つドキュメントを挿入しようとすると、エラーが発生します。
コレクションの表に_id
フィールドがないドキュメントを挿入すると、高速参照用に索引付けられた一意の値とともに自動的に追加されます。二面性ビュー・コレクションに挿入するドキュメントには、_id
フィールドを明示的に含める必要があります。
非二面性ビュー・コレクションには、_id
ドキュメント識別子フィールドは必要ありませんが、ある場合は、コレクション全体でその値が一意であることを確認する必要があります。
ドキュメントAPIでは通常、挿入する文書に_id
ドキュメント識別子フィールドが含まれますが、SQLを使用した列DATA
への"サイドバンド"挿入では含まれないことがあります。
_id
は、特定のコレクション全体で一意である必要があります。異なるコレクションには、_id
値が同じであるドキュメントを含めることができます。この機能の用途の1つは、関連コレクションが関連情報を参照することです。たとえば、customer_profile
コレクションとcustomer_complaints
コレクションは、同じ_id
値を使用して、実質的に同じ顧客を参照できます。
ドキュメント識別子の値はコレクション全体で一意であるため、ドキュメントAPIではそれを使用してドキュメントに直接アクセスできます。これがドキュメント識別子の目的です。(非二面性) JSONコレクション・ビューにドキュメント識別子フィールドがない場合でも、ドキュメントAPIはコレクション内のドキュメントを読み取ることができますが、問合せ式の検索操作のみを使用します。
SQLファンクションjson_id
を使用して、指定するドキュメント識別子フィールドの値を作成できます。json_id
によって返される値は、SQL型RAW
の識別子であり、実質的にグローバルに一意です。必要なSQL文字列引数によって、RAW
値の種類が決まります。文字列'OID'
では、12バイトのRAW
値が返されます。文字列'UUID'
では、16バイトのRAW
値が返されます。
フィールド_id
がOracleによって自動的に作成される場合、その値は引数'OID'
を指定してjson_id
を起動することで提供されます。返される12バイトのRAW
OID値は、フィールド_id
のJSON
型の値に対応します。OID (オブジェクト識別子)形式は、Oracle Database API for MongoDBと互換性があります。(UUIDの形式は、IETFのUniversally Unique IDentifiers (UUIDs)で提案された標準RFC 9562を順守しています。)
JSONコレクション表または二面性ビューにドキュメントを挿入する場合、型JSON
のインスタンスとして値を返すRETURNING
句を指定したSQL INSERT
コマンドを使用して、その_id
フィールドの値を取得できます。これは、フィールドが自動的に追加される場合に便利です。
たとえば、次のPL/SQLコードは、JSON
型変数id
の値を、自動的に指定されたフィールド_id
の値に設定します:
DECLARE id JSON;
BEGIN
INSERT INTO my_collection mc
VALUES (JSON('{"a" : 42}'))
RETURNING mc.data."_id" INTO id;
DBMS_OUTPUT.put_line(json_serialize(id));
END
このJavaコードでは同じことをしています — JSON
型の変数id
の値に、自動的に指定されたフィールド_id
の値を設定します:
String sql = "INSERT INTO my_collection mc " +
"VALUES ('{\"a\" : 42}') " +
"RETURNING mc.data.\"_id\" INTO ?";
OraclePreparedStatement ocstmt = (OraclePreparedStatement) conn.prepareStatement(sql);
ocstmt.registerReturnParameter(1, OracleTypes.JSON);
ocstmt.executeUpdate();
rs = ocstmt.getReturnResultSet();
System.out.println("Retrieved _id : " + rs.getObject(1, OracleJsonBinary.class));
JSONコレクションは実際には特定の種類のデータベース表またはビューですが、ドキュメント中心のクライアント・アプリケーションでは表、ビューまたは列を気にしません。Oracle DatabaseドキュメントAPI (Oracle Database API for MongoDBおよびSimple Oracle Document Access (SODA))によって提供される操作を使用して、コレクションおよび文書のみを考慮します。各APIには、独自の文書およびコレクション操作があります。
JSONコレクション表には、JSON文書が格納されます。このようなコレクションは、CREATE JSON COLLECTION TABLE
を使用して作成します。(例6-2を参照してください。)
JSONコレクション・ビューは、JSON文書を基礎となるリレーショナル・データにマップします。次の2種類があります:
-
JSONリレーショナル二面性ビューは、直接更新可能にできます脚注2。つまり、文書(または文書の一部)を、問い合せるのみでなく、直接挿入、更新および削除できます。
二面性ビューでサポートされる文書には、常にドキュメント識別子フィールド
_id
があります。このようなコレクションは、
CREATE JSON RELATIONAL DUALITY VIEW
を使用して作成します。(「二面性ビューの作成」を参照してください。) -
非二面性JSONコレクション・ビューは、直接(つまり、文書を使用する)は更新できません。ドキュメントAPIを使用して、文書を問合せすることしかできません。
このようなコレクションは、
CREATE JSON COLLECTION VIEW
を使用して作成します。(例6-3を参照してください。)
二面性ビューと非二面性ビューのどちらも、ビューの基にある表データを更新することで、サポートされている文書を間接的に更新できます。それらの相違点は、非二面性ビューが直接的に文書更新可能でないことです。
ヒント:
読取り専用コレクション・ビューのみが必要な場合でも、一般的に、非二面性ビューよりも二面性ビューを使用することをお薦めします。これは、二面性ビューの方が問合せ最適化のパフォーマンスが高いためです。
便宜上、JSONコレクション(表、ビューまたは二面性ビュー)を作成するたびに、指定したコレクション名に対してシノニムが自動的に作成されます。指定した名前が引用符で囲まれていない場合、シノニムは同じ名前ですが引用符で囲まれます。指定した名前が引用符で囲まれている場合、シノニムは同じ名前ですが引用符で囲まれません。引用符で囲まれた名前に、引用符で囲まれていない名前で許可されていない文字が1つ以上含まれている場合、シノニムは作成されません。シノニムを作成すると、コレクションの名前は、引用符で囲まれているかどうかに関係なく、実質的に常に大文字と小文字が区別されるようになります。『Oracle Database SQL言語リファレンス』の「CREATE SYNONYM」を参照してください。
二面性ビューでは、SQL/JSON生成関数を使用して、サポートされているJSON文書と、その生成に使用される基礎となるリレーショナル・データとの間のマッピングを定義します。非二面性コレクション・ビューでも生成関数を使用できますが、一般的には(単一の)JSONオブジェクトを返すかぎり、リレーショナル・データに対して任意のSQL問合せを使用できます。
JSON二面性ビューおよびJSONコレクション表は、JSONデータ(二面性ビューの場合は生成され、コレクション表の場合は格納される)に関しては互換性があります。SQL*Plus describe
コマンドが示すように、それぞれにDATA
という名前の単一のJSON
型のオブジェクト列があり、最上位レベルにドキュメント識別子フィールド_id
があります。
関連項目:
『JSONリレーショナル二面性開発者ガイド』の「JSONリレーショナル二面性ビューの概要」
JSONコレクションは固定形状(行ごとに1つのJSON文書(オブジェクト)を持つ単一のJSON
型オブジェクト列(DATA
))であるため、ドキュメントAPIは、表、列または行を気にすることなく、文書に直接アクセスおよび操作できます。
CREATE JSON COLLECTION TABLE
およびCREATE JSON COLLECTION VIEW
は、CREATE TABLE
およびCREATE VIEW
の基礎となる使用を簡素化するマクロと考えることができます。CREATE JSON COLLECTION TABLE
では、CREATE TABLE
と同じオプションのほとんどを使用できます。(例10-1に、PARTITION BY RANGE
句の使用例を示します)。
最終的には「単なる表」であるため、通常の表を使用するほとんどの方法でJSONコレクション表を使用できます。特に、GoldenGateを使用して、Oracle DatabaseとMongoDBなどのJSONドキュメント・データベース間など、データベース間でコレクション表をレプリケートできます。(GoldenGateを使用して二面性ビューをレプリケートすることもできます。)
JSONコレクション表には、ETAGサポートという追加オプションがあります。キーワードWITH ETAG
とともにCREATE JSON COLLECTION TABLE
を指定した場合、各JSON文書にはドキュメント処理フィールド_metadata
が含まれ、その値は唯一のフィールドとしてetag
を持つオブジェクトです。これは、JSON二面性ビューの場合と同じです。詳細は、「カーレースの例、二面性ビュー」を参照してください。(キーワードWITH ETAG
を使用しない場合、_metadata
フィールドはありません。)
フィールドetag
の値は、文書が書き込まれるたびに更新されるため、文書がデータベースから最後に読み取られてから変更されたかどうかを確認するために使用できます。この動作を使用して、オプティミスティックな同時実行性を実装できます。「二面性ビューでのオプティミスティックな同時実行性制御の使用」を参照してください。
JSONコレクション表を作成するときに、その表に対して1つ以上の式列を定義することもできます。これらの列は仮想列です。値は列に格納されず、列にアクセスするたびにSQL問合せ式を評価した結果として算出されます。式列はデフォルトでは非表示です。
列DATA
またはユーザー定義の式列に対して制約を指定することもできます(例6-1を参照)。式列の最も重要な用途は、JSONフィールド値に基づいてコレクションをパーティション化することです(例10-1を参照)。
例6-1 仮想列および制約を使用したJSONコレクション表の作成
この例では、JSONコレクション表employeeを作成します。JSON型の列DATA
に加えて、表には非表示の仮想列SALARY
が含まれます。この列の値は、最上位レベルのJSONフィールドsalary
の値で、SQL数値です。json_value
式は、項目メソッドnumber()
を使用してフィールド値をSQL数値として解釈して、フィールド値を抽出します。
仮想列SALARY
の値は、ゼロより大きい値に制約され、これにより、列DATA
のフィールドsalary
の値も制約されます。
CREATE JSON COLLECTION TABLE employee
(salary AS (json_value(DATA, '$.salary.number()')),
CONSTRAINT sal_chk CHECK (salary > 0));
ALTER TABLE
を使用して、JSONコレクション表を変更(名前の変更、制約の追加/削除、ユーザー定義の仮想列の追加/削除、パーティション化の追加/削除など)できます。
様々な静的ディクショナリ・ビューを参照して、JSONコレクション表およびビューに関する情報を取得できます。
-
*_JSON_COLLECTIONS
— すべてのコレクション表、コレクション・ビューおよびJSONリレーショナル二面性ビューをリストします: 所有者、名前および型(コレクション表、非二面性コレクション・ビューまたは二面性ビュー)。 -
*_JSON_COLLECTION_TABLES
— すべてのコレクション表をリストします: 所有者、名前および文書にETAGメタデータ値が含まれているかどうか。 -
*_JSON_COLLECTION_VIEWS
— すべてのコレクション・ビュー(所有者と名前)をリストします。
さらに:
-
表(
*_TABLES
)およびビュー(*_VIEWS
)のディクショナリ・ビューも、コレクション表およびコレクション・ビューをリストします。 -
データベース・オブジェクト(
*_OBJECTS
)のディクショナリ・ビューも、コレクション表およびコレクション・ビュー(列OBJECT_TYPE
がそれぞれTABLE
およびVIEW
)をリストします。
関連項目:
-
CREATE JSON COLLECTION TABLE
の詳細は、『Oracle Database SQL言語リファレンス』のJSON記憶域句に関する項を参照してください -
CREATE JSON COLLECTION VIEW
の詳細は、『Oracle Database SQL言語リファレンス』のCREATE VIEWに関する項を参照してください -
『Oracle Databaseリファレンス』の「ALL_JSON_COLLECTIONS」
-
『Oracle Databaseリファレンス』の「ALL_JSON_COLLECTION_TABLES」
-
『Oracle Databaseリファレンス』のALL_JSON_COLLECTION_VIEWSに関する項
-
『Oracle Databaseリファレンス』の「ALL_OBJECTS」
-
『Oracle Databaseリファレンス』の「ALL_TABLES」
-
『Oracle Databaseリファレンス』の「ALL_VIEWS」
例6-2 JSONコレクション表の作成
この例では、コレクション表j_purchaseorder
を作成します。DATA
という名前の単一のJSON
型のオブジェクト列があります。
CREATE JSON COLLECTION TABLE j_purchaseorder;
この例を、例4-1 (2つのリレーショナル列id
とdate_loaded
、およびJSON
型の列data
がある、通常の表を作成する)と対比してください。
CREATE JSON COLLECTION TABLE
の詳細は、『Oracle Database SQL言語リファレンス』のJSON記憶域句に関する項を参照してください
例6-3 (非二面性) JSONコレクション・ビューの作成
この例では、表hr.employees
のリレーショナル・データから非二面性、読取り専用コレクション・ビューempview
を作成します。
CREATE JSON COLLECTION VIEW empview AS
SELECT JSON {'_id' : employee_id,
last_name,
'contactInfo' : {email, phone_number},
hire_date,
salary}
FROM hr.employees;
データは、列employee_id
、last_name
、email
、phone_number
、hire_date
およびsalary
から選択されます。結果のJSONドキュメントは、フィールド_id
、LAST_NAME
、contactInfo
、HIRE_DATE
およびSALARY
を持つオブジェクトです。フィールドcontactInfo
の値は、フィールドEMAIL
およびPHONE_NUMBER
を持つオブジェクトで、その値は列email
およびphone_number
から取得されます。
CREATE JSON COLLECTION VIEW
をCREATE VIEW
のみに置き換えた場合、結果は同じデータを持つ単一のDATA
列を持つ、通常の読取り専用ビューになります。コレクション・ビューにはなりません。Oracle Database API for MongoDBやSimple Oracle Document Access (SODA)などのドキュメントAPIを使用して直接問い合せることはできません。
CREATE JSON COLLECTION VIEW
の詳細は、『Oracle Database SQL言語リファレンス』のCREATE VIEWに関する項を参照してください
関連トピック
親トピック: JSONデータの格納および管理
脚注の凡例
脚注1: ドキュメント識別子は、ドキュメント・キーと呼ばれることもあります。脚注2: 二面性ビューを作成するときに、それに対して許可する更新の種類を指定できます。それをしない場合は、デフォルトでそれが読取り専用になります。