InterSystems IRIS ドキュメント データベース (DocDB) の概要
InterSystems IRIS® Data Platform の DocDB は、データベース・データの保存と取得のための機能です。従来の SQL のテーブルおよびフィールド (クラスおよびプロパティ) データの保存や取得との互換性はありますが、これとは別の機能です。また、Web ベースのデータ交換をサポートする JSON (JavaScript Object Notation) がベースになっています。InterSystems IRIS は、DocDB データの作成と照会のための SQL サポートを提供するだけでなく、REST や ObjectScript での DocDB データベースおよびアプリケーションの開発のためのサポートも提供します。
InterSystems IRIS ドキュメント データベースは、本質的に、スキーマレスなデータ構造です。つまり、各ドキュメントがそれぞれ独自の構造を持ちます。この構造は、同じデータベース内の他のドキュメントと異なる場合もあります。これには、事前定義されたデータ構造を必要とする SQL よりも優れたメリットがいくつか存在します。
ここでは、「ドキュメント」という用語が、業界全体で使用される特殊な専門用語として、動的なデータ保存構造の意味で使用されます。DocDB で使用される「ドキュメント」をテキスト・ドキュメントや文書と混同しないようにしてください。
機能およびメリット
InterSystems IRIS DocDB は、以下のような主要機能を備えています。
-
アプリケーションの柔軟性 : ドキュメントは事前定義されたスキーマを必要としません。これにより、アプリケーションでデータ環境の設定を速やかに行い、データ構造の変化に容易に順応することができます。これにより、データの迅速な取得が可能になります。ドキュメント・データベースは、データの構造を定義することなく、即座にデータの取得を開始できます。これは、Web ベースおよびソーシャル・メディアのデータ・ソースでよく見られる予測不能なデータ・フィードに最適です。データの本文の取得時、そのデータ内の構造が役立つものであることが明らかになった場合、ドキュメントのデータ構造をさらに発展させることが可能です。既存の取得済みデータは、より高度に構造化されたこのデータ表現と共存できます。ドキュメントごとにデータ構造を決定し、これを適切に処理するかどうかはご使用のアプリケーションによります。これを行う方法の 1 つとして、ドキュメント構造のバージョンを表す key:value ペアの構築が挙げられます。したがって、ある JSON 構造から別の JSON 構造へのデータの変換は、データの取得やアクセスを妨げることなく段階的に行える場合もあれば、まったく行えない場合もあります。
-
スパース・データにおける効率性 : ドキュメントは、スパース・データの保存における効率性が非常に優れています。これは、特定のキーを持つ属性がコレクション内の一部のドキュメントに出現し、他のドキュメントには出現しないようにすることができるためです。ドキュメントはそれぞれ一組の定義済みキーを持つことができるため、同じコレクション内の他のドキュメントがまったく異なる一組の定義済みキーを持つことも可能です。それに対して、SQL では、すべてのレコードにそれぞれのキーが含まれている必要があります。スパース・データでは、多くのレコードが NULL 値のキーを持ちます。例えば、SQL の患者医療記録では、さまざまな診断、症状、および検査に関するフィールドが用意されていますが、大半の患者について、これらのフィールドのほとんどが NULL になります。使用されないこれらのフィールドには、すべてスペースが割り当てられます。DocDB の患者医療記録では、実際のデータが含まれるそれらのキーのみが表示されます。
-
階層データの保存 : DocDB は、階層構造データの保存における効率性が非常に優れています。key:value ペアでは、データをそのデータ内で無制限に入れ子にすることができます。つまり、階層データを正規化されていない状態で保存できます。SQL リレーショナル・モデルでは、階層データは、複数のテーブルを使用して正規化された状態で保存されます。
-
ダイナミック・データ型 : キーは、定義されたデータ型を持ちません。キーに割り当てられた値は、関連付けられたデータ型を持ちます。したがって、各ドキュメントの key:value ペアはそれぞれ 1 つのデータ型を持つことができるため、他のドキュメント内の同じキーの key:value ペアが異なるデータ型を持つことも可能です。データ型が固定されていないため、異なるデータ型を持つ新しい値を割り当てることで、実行時にドキュメント内の key:value ペアのデータ型を変更できます。
DocDB のこれらの機能は、アプリケーションの開発において重要な意味を持ちます。従来の SQL 環境では、アプリケーションの開発で用いられるデータ構造は、データベースの設計によって確立されます。DocDB では、データ構造は、主にアプリケーション自体で提供されます。
DocDB のコンポーネント
DocDB のパッケージ名は %DocDB です。これには、以下のクラスが含まれています。
-
%DocDB.DatabaseOpens in a new tab: ドキュメントの管理に使用される ObjectScript 永続クラスです。データベースは、%DocDB.DocumentOpens in a new tab を拡張する永続クラスによって実装される一連のドキュメントです。このクラスのメソッドを使用することで、データベースの作成、既存データベースの取得、またはデータベースの削除を行ったり、データベース内でドキュメントの挿入、ドキュメントの取得、またはドキュメントの削除を行ったりすることができます。
-
%DocDB.DocumentOpens in a new tab: ドキュメント・データの保存に使用される構造です。ドキュメント ID、最終変更日、およびドキュメントの内容で構成されます。ドキュメントの内容は、%Doc プロパティで保存されます。データは、JSON ダイナミック・オブジェクトまたは JSON 動的配列として保存されます。ドキュメントは、複数の key:value ペア (オブジェクト) または順序どおりに並べられた値のリスト (配列) で構成されます。
-
%DocDB.RESTOpens in a new tab は、ドキュメント・データベースにアクセスするための DocDB REST API を実装します。
関連クラスは、JSON 構造を含めるのに使用され、JSON 配列と JSON key:value オブジェクトのサブクラスが含まれる %Library.DynamicAbstractObjectOpens in a new tab です。
データベースの作成
データベースは、抽象クラス %DocDB.DocumentOpens in a new tab を拡張する ObjectScript 永続クラスです。DocDB で使用するネームスペースごとにデータベースをインスタンス化する必要があります。ネームスペースごとに必要になるデータベースは 1 つのみです。通常、ネームスペース名と同じ名前が割り当てられます。
次の例は、クラス定義を使用してデータベースを作成する方法を示しています。
Class MyDBs.People Extends %DocDB.Document [ DdlAllowed ]
次の例は、パッケージ名の指定による、%CreateDatabase()Opens in a new tab メソッドを使用したデータベースの作成方法を示しています。
SET personDB = ##class(%DocDB.Database).%CreateDatabase("MyDBs.People")
次の例は、ISC.DM のデフォルトのパッケージ名の取得による、%CreateDatabase()Opens in a new tab メソッドを使用したデータベースの作成方法を示しています。
SET personDB = ##class(%DocDB.Database).%CreateDatabase("People")
%SYSTEM.DocDBOpens in a new tab クラスは、ドキュメント・データベースを管理するためのインタフェースを提供します。
ドキュメント・データベースの作成または取得、データベースへのドキュメントの入力、およびそれらのドキュメントからのデータの取得に使用される API メソッドの詳細については、“ドキュメントの管理” の章を参照してください。
JSON 構造
InterSystems IRIS ドキュメント データベースは、JSON ダイナミック・オブジェクトと JSON 動的配列をサポートします。これらの JSON 構造は、SET コマンドを使用して作成できます。
次の例は、JSON を使用して階層データを保存する方法を示しています。最初の SET は、入れ子になった JSON 構造の key:value ペアおよび配列を含む動的な抽象オブジェクトを作成します。その後、この例では、動的な抽象オブジェクトが JSON 文字列に変換され、その JSON 文字列がドキュメントとして既存のドキュメント・データベース内に挿入されます。
SET dynAbObj = {
"FullName":"John Smith",
"FirstName":"John",
"Address":{
"street":"101 Main Street",
"city":"Mapleville",
"state":"NY",
"postal code":10234
},
"PhoneNumber":
[
{"type":"home","number":"212-456-9876"},
{"type":"cell","number":"401-123-4567"},
{"type":"work","number":"212-444-5000"}
]
}
SET jstring = dynAbObj.%ToJSON() // dynamic abstract object to JSON string
DO personDB.%FromJSON(jstring) // JSON string inserted into document database
この例では、FullName は単純な key:value ペアとして保存されます。Address は、key:value ペアで構成されるオブジェクトして保存されるサブ構造を持ちます。PhoneNumber は、配列として保存されるサブ構造を持ちます。
詳細は、"JSON の使用" の “ダイナミック・エンティティの作成と変更” を参照してください。
ドキュメント
ドキュメントは、作成したデータベース・クラスのインスタンスの %DocOpens in a new tab プロパティで保存されます。これは、次の例で示されています。この例では、%Doc プロパティで JSON 配列が保存されます。
SET jarry = ["Anne","Bradford","Charles","Deborah"]
SET myoref = ##class(MyDBs.DB1).%New()
SET myoref.%Doc = jarry
SET docoref = myoref.%Doc
WRITE "%Doc property oref: ",docoref,!
WRITE "%Doc Property value: ",docoref.%ToJSON()
既定では、%Doc のデータ型は %Library.DynamicAbstractObjectOpens in a new tab です。これは、JSON オブジェクトまたは JSON 配列の保存に使用されるデータ型です。%CreateDatabase()Opens in a new tab メソッドで異なるデータ型を指定できます。
その他のデータベース・プロパティ :
-
%DocumentIdOpens in a new tab は、ドキュメントを識別する一意の整数を含む IDENTITY プロパティです。%DocumentId は 1 からカウントされます。ほとんどの場合、%DocumentId 値は、システムによって割り当てられます。%DocumentId は一意である必要があります。%DocumentId は、連続的に割り当てるとは限らず、割り当て順序内で欠番が生じる場合もあります。ドキュメント・データベースは、%DocumentId 値の IdKey インデックスも自動的に生成します。
-
%LastModifiedOpens in a new tab は、ドキュメント・インスタンスの定義時の UTC タイムスタンプを記録します。
正規化されていないデータ構造
以下に示すのは、従来の SQL の正規化されたリレーショナル・データ構造の JSON の例です。これは、2 つのドキュメントで構成されます。これらのドキュメントは、2 つの異なるコレクションに含まれる場合もあります。
{
"id":123,
"Name":"John Smith",
"DOB":"1990-11-23",
"Address":555
}
{
"id":555,
"street":"101 Main Street",
"city":"Mapleville",
"state":"NY",
"postal code":10234
}
以下に示すのは、入れ子になったデータ構造を含むコレクション内の単一ドキュメントとして指定された、正規化されていない同一のデータです。
{
"id":123,
"Name":"John Smith",
"DOB":"1990-11-23",
"Address":{
"street":"101 Main Street",
"city":"Mapleville",
"state":"NY",
"postal code":10234
}
}
SQL では、最初のデータ構造から 2 つ目のデータ構造に変換する場合、テーブル・データの定義を変更してからデータを移行する必要があります。
DocDB では、固定スキーマが存在しないため、これらの 2 つのデータ構造は、同じデータの異なる表現として共存できます。アクセスするデータ構造をアプリケーション・コードで指定する必要があります。データは、新しいデータ構造に移行することもでき、古いデータ構造形式のままにしておくこともできます。後者の場合、新しいデータ構造を使用してデータにアクセスする際に毎回データが移行されます。
JSON データ構造の詳細は、このマニュアルの “柔軟なデータ構造” の章を参照してください。
データ型とデータ値
DocDB では、キーはデータ型を持ちません。しかしながら、DocDB にインポートされたデータ値は、関連付けられたデータ型を持つことができます。データ型は特定の値に関連付けられるため、値を他の値に置換した場合、そのレコードの key:value ペアのデータ型が変更される場合があります。
InterSystems IRIS DocDB には、予約語や特別な名前付け規約が一切存在しません。key:value ペアでは、任意の文字列をキーとして使用でき、任意の文字列または数値を値として使用できます。キー名は、"name":"name" のように値と同一にすることができます。キー名は、インデックス名と同一にすることができます。
以下のテーブルのように、InterSystems IRIS DocDB は、データ値を JSON 値として表します。
データ値 | 表現 |
---|---|
文字列 | 文字列 |
数値 | 数値は、"キャノニック形式" で表されます。ただし、例外として、1 から -1 までの JSON 小数は先頭に整数ゼロを付けて表されます (例 : 0.007)。対応する InterSystems IRIS の数値は、先頭に整数ゼロを付けずに表されます (例 : .007)。 |
$DOUBLE の数値 | "IEEE 倍精度 (64 ビット) 浮動小数点数" として表されます。 |
非表示文字 |
JSON では、以下の非表示文字のエスケープ・コード表現が用意されています。 $CHAR(8): ”\b” $CHAR(9): ”\t” $CHAR(10): ”\n” $CHAR(12): ”\f” $CHAR(13): ”\r”その他の非表示文字はすべて、エスケープされた 16 進数で表されます。例えば、$CHAR(11) は ”\u000b” として表されます。エスケープされた 16 進数 (Unicode) 表記を使用して表示可能文字を表すこともできます。例えば、ギリシャ文字の小文字のアルファは、”\u03b1” として表すことができます。 |
その他のエスケープ文字 |
JSON は、2 つの表示可能文字 (二重引用符文字とバックスラッシュ文字 (円記号)) をエスケープします。 $CHAR(34): ”\”” $CHAR(92): ”\\” |
特殊な JSON 値
特殊な JSON 値は、JSON オブジェクトと JSON 配列内でのみ使用できます。これらの値は、対応する特殊な ObjectScript 値とは異なります。特殊な JSON 値は、引用符なしで指定されます (同じ値を引用符で囲んで指定すると、通常のデータ値として扱われます)。これらの値は大文字と小文字の任意の組み合わせで指定でき、すべて小文字として保存されます。
-
JSON では、特殊な null 値を使用して、値が存在しないことを表します。実際の値が存在しない場合は、通常、ドキュメント・データベースに key:value ペアは含まれないため、null は特別な条件でのみ使用されます (予想値のプレースホルダなど)。この null の使用法は、以下の例を参照してください。
SET jsonobj = {"name":"Fred","spouse":null} WRITE jsonobj.%ToJSON()
-
JSON では、特殊な true 値および false 値を使用してブーリアン値を表します。このブーリアン値の使用法は、以下の例を参照してください。
SET jsonobj = {"name":"Fred","married":false} WRITE jsonobj.%ToJSON()
ObjectScript では、0 と 1 を使用してブーリアン値を指定します (実際は、"true" は 1 に限らず、ゼロ以外の任意の数値で表すことができます)。これらの値は、JSON ドキュメント内でブーリアン値としてサポートされません。
いくつかの特殊な場合において、JSON では、構文をわかりやすくするために括弧を使用します。
-
null、true、または false という名前でローカル変数を定義する場合、これを特殊な JSON 値ではなく、ローカル変数として扱うために、JSON 内で括弧を使用する必要があります。詳細は、以下の例を参照してください。
SET true=1 SET jsonobj = {"bool":true,"notbool":(true)} WRITE jsonobj.%ToJSON()
-
式内で ObjectScript の "後続関係演算子" (]) を使用する場合、これを JSON 配列の終端文字ではなく後続関係演算子として扱うために、JSON 内で括弧を使用する必要があります。次の例では、照合順で b が a の後に続くかどうかを式 b]a がテストし、ObjectScript のブーリアン値を返します。後続関係式は括弧で囲む必要があります。
SET a="a",b="b" SET jsonarray=[(b]a)] WRITE jsonarray.%ToJSON()