8.2 JSONフレックス列からドキュメントへのフィールドのマージ
二面性ビューのフレックス列では、フィールドが事前定義されていないJSONオブジェクトが格納されます(基になる表内)。それらは、基になる特定の列に個別にマップされません。挿入または更新したドキュメント内のオブジェクトの認識されていないフィールドは、そのオブジェクトの、基になる表のフレックス列に自動的に追加されます。
したがって、二面性ビューを再定義せずに、二面性ビューによって生成されたドキュメント・オブジェクトに、そのオブジェクトの基になるフレックス列により、フィールドを追加できます。これにより、二面性ビュー、およびそれでサポートされているドキュメントに対して、別の種類のスキーマ柔軟性が提供されます。指定された基になる表に、フレックスとしてそのビュー内で識別された列がない場合、新しいフィールドは、その表によって生成されたオブジェクトに自動的には追加されません。このような柔軟性が必要な場合はフレックス列を追加します。
なお、表のフレックス列という呼び方は技術的には正しくありません。フレックス列は、フレックスとして指定されている二面性ビュー列です(そのビューの場合にフレックス)。
表person
にリレーショナル列が3つとJSON
型列extras
があり、それらの値がJSONオブジェクトである必要がある場合を考えてみます。
CREATE TABLE person (
pid NUMBER PRIMARY KEY,
first VARCHAR2(20),
last VARCHAR2(20),
extras JSON (OBJECT));
二面性ビューperson_merge_dv
では、列extras
を除く表person
の各列がドキュメント・フィールドにマップされています。列extras
がフレックス列として宣言されています。GraphQLおよびSQLでのビュー定義を次に示します:脚注1
GraphQL:
CREATE JSON DUALITY VIEW person_merge_dv AS
person @update @insert @delete
{_id : pid,
firstName : first,
lastName : last,
extras @flex};
SQL:
CREATE JSON RELATIONAL DUALITY VIEW person_merge_dv AS
SELECT JSON {'_id' : p.pid,
'firstName' : p.first,
'lastName' : p.last,
p.extras AS FLEX COLUMN}
FROM person p WITH UPDATE INSERT DELETE;
ビューperson_merge_dv
にドキュメントを挿入すると、表person
によって生成されたオブジェクトでは認識されないフィールド(この場合はフィールドnickName
)が、フレックス列person.extras
に追加されます。表person
によって生成されたオブジェクトは、ドキュメントの最上位オブジェクトです。フィールドnickName
は、そのオブジェクトに追加されます。
INSERT INTO person_merge_dv VALUES ('{"_id" : 2,
"firstName" : "John",
"nickName" : "Anon Y",
"lastName" : "Doe"}');
挿入されたドキュメントを選択すると、フレックス列のオブジェクトに格納されたフィールド、および他の列に明示的にマップされたフィールドが同じオブジェクト内に存在することがわかります。フィールドnickName
は、フレックス列内のオブジェクトから、フレックス列の表person
によって生成されたオブジェクトにマージされました。
SELECT pdv.data FROM person_merge_dv pdv
WHERE pdv.data."_id" = 2;
{"_id":2,"firstName":"John","lastName":"Doe","nickName":"Anon Y"}
表person
を問い合せると、フィールドnickName
が、フレックス列extras
に格納されているJSONオブジェクトに含まれていることがわかります。(ここではビューperson_merge_dv
へのドキュメント挿入の前に表person
が空であると想定していますが、次を参照してください。)
SELECT p.* FROM person p;
PID FIRST LAST EXTRAS
--- ----- ---- ------
2 John Doe {"nickName":"Anon Y"}
列person.extras
が別の二面性ビューと共有されている場合はその内容に対する変更は両方のビューに反映されることに注意してください。このことが必要な場合もそうでない場合もあります。このことに留意してください。
たとえば、表person
はここでは「JSON列からドキュメントへの値の埋込み」においてと同様に定義されています。「JSON列からドキュメントへの値の埋込み」でオブジェクト{"middleName":"X", "nickName":"Anon X"}
が同じ列person.extras
に挿入されると考えると、その挿入に加えて二面性ビューperson_merge_dv
への前述の挿入が実行された結果、両方のオブジェクトがその表に存在することになります。
SELECT p.* FROM person p;
PID FIRST LAST EXTRAS
--- ----- ---- ------
1 Jane Doe {"middleName":"X","nickName":"Anon X"}
2 John Doe {"nickName":"Anon Y"}
どちらの二面性ビューでもJane DoeとJohn Doeのデータが使用されますが、列extras
内のオブジェクトは別々の方法で使用されます。ビューperson_embed_dv
では、それらがフィールドmoreInfo
の値として埋め込まれます。ビューperson_merge_dv
では、それらのフィールドが最上位でマージされます。
SELECT pdv.data FROM person_embed_dv pdv;
{"_id":1,"firstName":"Jane","lastName":"Doe",
"moreInfo":{"middleName":"X","nickName":"Anon X"}}
{"_id":2,"firstName":"John","lastName":"Doe",
"moreInfo":{"nickName":"Anon Y"}}
SELECT pdv.data FROM person_merge_dv pdv;
{"_id":1,"firstName":"Jane","lastName":"Doe",
"middleName":"X","nickName":"Anon X"}
{"_id":2,"firstName":"John","lastName":"Doe",
"nickName":"Anon Y"}
別々のビューで、同じ情報を別々の形式で存在させることができます。これは、二面性ビューにも、非二面性ビューにも当てはまります。
ノート:
表内のフレックス列は単なる二面性ビュー構成メンバーです。その表自体では、"フレックス列"の意味も動作もありません。同じ表に、様々な二面性ビュー内のフレックス列として、または同じ二面性ビュー内の様々な場所にあるフレックス列として使用される、様々な列を含めることができます。本当にその列の内容をそこで共有する必要がある場合を除き、1つの列(すべての型)を様々な場所で共有しないでください。
親トピック: 二面性ビューでのJSON列によるスキーマ柔軟性
脚注一覧
脚注1: これは、「JSON列からのドキュメントへの値の埋込み」での二面性ビュー定義とは異なります。つまり、(1)列extras
はフレックス列としてラベル付けされており、(2)それはフィールドにマップされません。