1 Oracle DatabaseのJSON

Oracle Databaseは、トランザクション、索引付け、宣言的問合せおよびビューを含むリレーショナル・データベースの機能を使用してJavaScript Object Notation (JSON)データをネイティブにサポートしています。

このマニュアルでは、Oracle Databaseに格納されたJSONデータを扱うためのデータベース言語および機能の使用について取り上げます。特に、SQLおよびPL/SQLとJSONデータの連携方法について説明します。

ノート:

Oracleでは、データベース内に格納されたJSONデータへのアクセス用に、Simple Oracle Document Access (SODA) APIファミリも提供しています。SODAは、リレーショナル・データベース機能やSQLおよびPL/SQLなどの言語に関する知識を使用しないスキーマレス・アプリケーション開発向けに設計されています。データベースで文書がどのように格納されているかを把握しなくても、文書コレクションのOracle Databaseでの作成および格納や、それらの文書の取得および問合せの実行を可能にします。

次のように、いくつかの種類のSODAの実装があります。

  • SODA for REST — HTTPコールを実行できる任意の言語を使用して、Representational State Transfer (REST)のリクエストでは、コレクションおよび文書操作を実行します。

  • SODA for Java — Javaクラスおよびインタフェースは、データベース、コレクションおよび文書を表します。

  • SODA for PL/SQL — PL/SQLオブジェクト型は、コレクションおよび文書を表します。

  • SODA for C — Oracle Call Interface (OCI)のハンドルは、コレクションおよび文書を表します。

SODAの詳細は、ドキュメント・ストアとして機能するOracleを参照してください。

1.1 Oracle DatabaseにおけるJSONの概要

Oracle Databaseは、トランザクション、索引付け、宣言的問合せおよびビューを含むリレーショナル・データベースの機能を使用してJSONをネイティブにサポートしています。リレーショナル・データとは異なり、データを定義するスキーマを必要とせずに、JSONデータをデータベース内に格納したり、索引付けおよび問合せを行うことができます。

(JSONデータは、それを格納する表および列を定義するためにデータベース・スキーマが使用されている場合であっても、スキーマレスとなります。そのスキーマにはJSONデータ自体の構造は指定されていません。)

多くの場合、JSONデータは、Oracle NoSQL DatabaseおよびOracle Berkeley DBなどのNoSQLデータベースに格納されています。これらを使用すると、スキーマに基づいていないデータを格納および取得できますが、これらにはリレーショナル・データベースの厳密な整合性モデルは用意されていません。

このような短所を補うために、場合によっては、NoSQLデータベースと並行してリレーショナル・データベースが使用されます。したがって、NoSQLデータベースに格納されたJSONデータを使用するアプリケーションでは、データの整合性をそれ自体で確保する必要があります。

JSONがOracle Databaseでネイティブにサポートされることで、このような負荷を未然に防ぐことができます。トランザクション、索引付け、宣言的問合せ、ビューなどの、JSONで使用するためのリレーショナル・データベース機能のメリットすべてを利用できます。

構造化問合せ言語(SQL)を使用したデータベース問合せは宣言的です。Oracle Databaseでは、SQLを使用してJSONデータをリレーショナル・データに結合できます。また、JSONデータをリレーショナルに投影できるため、JSONデータはリレーショナルなプロセスおよびツールで使用できるようになります。さらに、Oracle Databaseの外部で外部表に格納されたJSONデータをデータベース内で問い合せることもできます。

データベースに格納されたJSONデータには、Oracle Call Interface (OCI)、Java Database Connectivity (JDBC)などの、他のデータベース・データへのアクセスと同じ方法でアクセスできます。

JSON言語標準では、JSONデータはテキスト形式で定義されます。標準構文ではUnicode文字で構成されます。Oracle Databaseでは、一般的なSQLデータ型VARCHAR2CLOBおよびBLOBを使用して、JSONデータを未解析文字データとしてテキスト形式で格納できます。

列値が有効なJSONインスタンスであることを保証するために、常にis_jsonチェック制約を使用することをお薦めします例4-1を参照してください。

データベース表のJSON列

Oracle Databaseでは、JSON文書の格納に使用される表に制限はありません。JSON文書が含まれる列は、他のどんな種類のデータベース・データとも共存させることができます。1つの表に、JSON文書が含まれる複数の列を含めることも可能です。

Oracle DatabaseをJSONのドキュメント・ストアとして使用する場合、JSON列が含まれる表には、通常、JSON以外のハウスキーピング列がいくつか含められます。これらは、通常JSON文書に関するメタデータをトラッキングします。

JSONを使用して、主にリレーショナル・アプリケーションに柔軟性を追加する場合、いくつかの表にはJSON文書用の列も作成されることが考えられます。これらの列は、リレーショナル・モデルに直接マッピングされないアプリケーション・データの管理のために使用されます。

定義上、テキストのJSONデータは、Unicodeエンコーディング(UTF-8またはUTF-16)を使用してエンコードされます。非Unicode文字セットで格納されたテキスト・データはJSONデータであるかのように使用できますが、この場合、この文字セットはデータの処理時に自動的にUTF-8に変換されます。

JSONデータでのSQLの使用

SQLでは、特別な関数や条件または単純なドット表記法を使用して、Oracle Databaseに格納されたJSONデータにアクセスできます。ほとんどのSQLファンクションおよび条件はSQL/JSONの標準に属していますが、一部はOracleに固有のものです。

  • SQL/JSON問合せファンクションjson_valuejson_queryおよびjson_table

    これらは、SQL/JSONパス式をJSONデータに対して評価し、SQL値を生成します。

  • Oracle SQL条件json_textcontains、およびSQL/JSON条件json_existsis jsonis not json

    条件json_existsでは、特定のJSONデータが存在するかどうかがチェックされます。json_textcontainsでは、JSONデータの全文問合せを実行できます。is jsonおよびis not jsonでは、特定のJSONデータが整形式であるかどうかがチェックされます。

    json_existsおよびjson_textcontainsでは、SQL/JSONパス式と一致するデータがチェックされます。

  • 問合せファンクションjson_valuejson_queryを組み合せたような動作の単純なドット表記法

    これは、SQLオブジェクト・アクセス式、つまり抽象データ型(ADT)の属性ドット表記法に似ています。これが、データベースのJSONデータを問い合せる最も簡単な方法です。

  • SQL/JSONの生成関数であるjson_objectjson_arrayjson_objectaggおよびjson_arrayagg

    これらは、JSONオブジェクトおよび配列データを(SQL値として)生成するためにSQLデータを集めます。

  • Oracle SQL条件json_equal: 2つのJSON値が同じかどうかをテストします。

  • Oracle SQL集計関数json_dataguide

    これにより、データ・ガイドであるJSONデータが生成され、これを使用してデータベース内の他のJSONデータの構造およびコンテンツに関する情報を検出できます。

問合せのシンプルな例として、表j_purchaseorder(ここでは、poの別名を使用)のJSON列po_documentに格納された文書のドット表記法の問合せを次に示します。これは、すべての発注書の要求者を取得します(JSONフィールドRequestor)。

SELECT po.po_document.Requestor FROM j_purchaseorder po;

JSONデータでのPL/SQLの使用

SQLコードまたはJSON用のPL/SQLオブジェクト型を使用して、PL/SQLコード内でJSONデータを操作できます。(PL/SQLで使用するSQLコード内では、空のJSONフィールド名は使用できません)

組込みのPL/SQLファンクションとして、SQLファンクションおよび条件json_valuejson_queryjson_objectjson_arrayjson_existsis jsonis not jsonおよびjson_equalも使用できます。

BOOLEANデータ型がないOracle SQLの場合と異なり、PL/SQLでは、次のようになります。

  • json_existsis jsonis not jsonおよびjson_equalは、ブール関数です。

  • json_valueは、BOOLEAN値を返すことができます。

JSON向けのPL/SQLオブジェクト型もあり、インメモリーJSONデータの細かい構成および操作に使用できます。テキストのJSONデータに戻って、イントロスペクション、変更およびシリアライズを行えます。

1.2 Oracle DatabaseでJSONを使用する前に

一般的に、Oracle DatabaseでJSONデータを扱う場合に実行するタスクには、(1)is jsonチェック制約を使用したJSON列の作成、(2)列へのJSONデータの挿入、(3)JSONデータの問合せがあります。

  1. 主キー列とJSON列がある表を作成し、JSON列に整形式のJSONデータのみを確実に含めるためにis jsonチェック制約を追加します。

    次の文では、主キーidとJSON列po_documentがある表j_purchaseorderを作成しています(例4-1も参照)。

    CREATE TABLE j_purchaseorder
      (id          VARCHAR2 (32) NOT NULL PRIMARY KEY,
       date_loaded TIMESTAMP (6) WITH TIME ZONE,
       po_document VARCHAR2 (32767)
       CONSTRAINT ensure_json CHECK (po_document IS JSON));
  2. Oracle Databaseで使用可能な任意のメソッドを使用してJSON列にJSONデータを挿入します。

    次の文では、SQL INSERT文を使用して、いくつかの単純なJSONデータを表j_purchaseorderの3つ目の列(これが列po_document。前を参照)に挿入します。ここでは、一部のJSONデータが省略されています(...)。これらの詳細は、例4-2を参照してください。

    INSERT INTO j_purchaseorder
      VALUES (SYS_GUID(),
              to_date('30-DEC-2014'),
              '{"PONumber"             : 1600,
                "Reference"            : "ABULL-20140421",
                "Requestor"            : "Alexis Bull",
                "User"                 : "ABULL",
                "CostCenter"           : "A50",
                "ShippingInstructions" : {...},
                "Special Instructions" : null,
                "AllowPartialShipment" : true,
                "LineItems"            : [...]}');
    
  3. JSONデータを問い合せます。戻り値は常に、JSON値を表すVARCHAR2インスタンスです。ここでは、単純な例をいくつか示します。

    次の問合せでは、JSON列po_document内の各文書から、スカラー値(JSON列po_document内のオブジェクトのフィールドPONumberの値であるJSON数値)を抽出しています(例14-1も参照)。

    SELECT po.po_document.PONumber FROM j_purchaseorder po;
    

    次の問合せでは、各文書から、JSON電話オブジェクトの配列(フィールドShippingInstructionsの値のオブジェクトのフィールドPhoneの値)を抽出しています(例14-2も参照)。

    SELECT po.po_document.ShippingInstructions.Phone FROM j_purchaseorder po;
    

    次の問合せでは、各文書から、複数の値(配列Phone内の各オブジェクトのフィールドtypeの値)を配列として抽出しています。戻される配列は、格納されているデータの一部ではありませんが、問合せによって自動的に構成されます。(配列要素の順序は指定されません。)

    SELECT po.po_document.ShippingInstructions.Phone.type FROM j_purchaseorder po;
    

1.3 JSONに対するOracle Databaseのサポート

JavaScript Object Notation (JSON)に対するOracle Databaseのサポートは、リレーショナル記憶域の使用範囲とJSONデータの問合せの使用範囲のベスト・フィットを実現することにより、リレーショナル問合せとJSON問合せを互いに連携して機能させることを目指しています。Oracle SQL/JSONサポートは、SQL標準のJSONサポートと密接に連携しています。

関連項目: