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の実装には、次の2種類があります。

  • SODA for Java: データベース、コレクションおよび文書を表すJavaクラス。

  • SODA for REST: HTTPコールを実行できる任意の言語を使用した、Representational State Transfer (REST)リクエストとしてのSODA操作。

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

トピック:

1.1 Oracle DatabaseにおけるJSONの概要

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

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

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

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

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

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

Oracle Databaseで、JSONデータは一般的なSQLデータ型であるVARCHAR2CLOBおよびBLOBを使用して格納されます(抽象SQLデータ型XMLTypeを使用して格納されるXMLデータとは異なる)。列値が有効なJSONインスタンスであることを確認するために、常にis_jsonチェック制約を使用することをお薦めします(例4-1を参照)。

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

データベース表のJSON列

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

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

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

JSONデータでのSQLの使用

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

  • SQL/JSONの生成関数であるjson_objectjson_arrayjson_objectaggおよびjson_arrayagg。これらは、JSONデータを(SQL値として)生成するためにSQLデータを集めます。

  • 同じことは、Oracle SQLの集計関数であるjson_dataguideにも当てはまりますが、この場合に生成されるJSONデータはデータ・ガイドです。これは、データベース内の他のJSONデータの構造および内容に関する情報を検出するために使用できます。

  • SQL/JSONの問合せ関数であるjson_valuejson_queryおよびjson_tableと、SQL/JSONの問合せ条件であるjson_existsis jsonis not jsonおよびjson_textcontains。これらは、SQL/JSONパス式をJSONデータに対して評価し、SQL値を生成します。

  • json_valuejson_queryの問合せ関数の組合せと同じように機能し、SQLオブジェクトのアクセス式と似たドット表記法(つまり、抽象データ型(ADT)の属性ドット表記法)。これが、データベースのJSONデータを問い合せる最も簡単な方法です。

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

SELECT po.po_document.Requestor FROM j_purchaseorder po;

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

一般に、SQLコードは、JSONデータにアクセスするSQLコードも含めて、PL/SQLコード内で使用できます。PL/SQLで使用するSQLコード内では、空のJSONフィールドは使用できません。

組込みのPL/SQLファンクションとして、json_valuejson_queryjson_objectjson_arrayおよびjson_existsのSQL/JSONファンクションおよび条件も使用できます。(PL/SQLでは、SQL条件json_existsはブール型関数です。)

BOOLEANデータ型がないOracle SQLとは異なり、PL/SQL BOOLEANは、SQL/JSONファンクションjson_valueの有効な戻りデータ型です。

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数値)を抽出しています(例11-1も参照)。

    SELECT po.po_document.PONumber FROM j_purchaseorder po;
    

    次の問合せでは、各文書から、JSON電話オブジェクトの配列(フィールドShippingInstructionsの値のオブジェクトのフィールドPhoneの値)を抽出しています(例11-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サポートと密接に連携しています。

関連項目: