グローバルの概要
多次元ストレージ・エンジンは、InterSystems IRIS® の主な機能の 1 つです。この機能により、アプリケーションはデータをコンパクトで効率的な多次元スパース配列に格納できます。このような配列はグローバルと呼ばれます。
グローバルとは、任意の型のデータを格納できる、添え字付き変数です。このデータはディスク上に保存され、"グローバル" という名前が示すように、複数のプロセス間でグローバルに利用できます。グローバルは、その名前の前に記述されたキャレット (^) で通常の変数と区別できます。
一般的にグローバルは多次元スパース配列とされます。以下に示すように、配列状の構文を持ちながらも、配列にあるすべての添え字にデータが存在するとは限らないからです。
^a(1,2,3) = 4
^a(1,2,5000) = 4
ただし、多くの言語における配列とは異なり、グローバルの添え字には、以下に示すように負数、実数、または文字列を使用できます。
^b(-4, "hello", 3.14) = 4
このため、多くの場合、グローバルの概念は、キーと値のペアで構成するディクショナリ、または入れ子構造のディクショナリとされています。以下の例では、学名に従って鳥の名前を格納しています。
^bird("Anatidae", "Aix", "sponsa") = "Wood Duck"
^bird("Anatidae", "Anas", "rubripes") = "American Black Duck"
^bird("Anatidae", "Branta", "leucopsis") = "Barnacle Goose"
^bird("Odontophoridae", "Callipepia", "californica") = "California Quail"
^bird("Odontophoridae", "Callipepia", "gambelii") = "Gambel's Quail"
多くの言語では、ディクショナリのデータに決まった順序がありません。つまり、ディクショナリのデータを取得すると、そのデータは不定の順序で返されることが考えられます。しかし、グローバルの場合、データは格納されたときの添え字に従ってソートされています。
そのため、グローバルはツリー構造で表現する方が正確です。ツリー構造では、各ノードに値やその子を置くことができます。この点で、普通はツリーのリーフのみにデータが存在する、入れ子になったディクショナリ・モデルよりも柔軟です。以下の例では、ルート・ノードにグローバルの説明を格納し、鳥類を表すノードにその分類の説明を格納しています。
^bird="Birds of North America"
^bird("Anatidae") = "Ducks, Geese and Swans"
^bird("Anatidae", "Aix", "sponsa") = "Wood Duck"
^bird("Anatidae", "Anas", "rubripes") = "American Black Duck"
^bird("Anatidae", "Branta", "leucopsis") = "Barnacle Goose"
^bird("Odontophoridae") = "New World Quails"
^bird("Odontophoridae", "Callipepia", "californica") = "California Quail"
^bird("Odontophoridae", "Callipepia", "gambelii") = "Gambel's Quail"
ツリー構造にデータを格納する様子を説明した動画は、"ツリー構造" を参照してください。
特徴
グローバルは、永続多次元配列での簡単なデータ格納法を提供します。
例えば、^Settings というグローバルを使用して、値 “Red” を キー “Color” と関連付けることができます。
SET ^Settings("Color")="Red"
グローバルの多次元性を利用して、さらに複雑な構造の定義が可能となります。
SET ^Settings("Auto1","Properties","Color") = "Red"
SET ^Settings("Auto1","Properties","Model") = "SUV"
SET ^Settings("Auto2","Owner") = "Mo"
SET ^Settings("Auto2","Properties","Color") = "Green"
グローバルには以下の機能があります。
-
使用の容易性 — グローバルは、他のプログラミング言語の変数と同様に使用が簡単です。
-
多次元 — 任意の添え字を使用して、グローバルでノードのアドレスを指定できます。例えば ^Settings("AUTO2","Properties","Color") の場合、添え字 Color は Settings グローバルで 3 番目のノードになります。添え字は、整数、数値、あるいは文字列値で、連続している必要はありません。
-
スパース — グローバル・ノードのアドレス指定をするための添え字は非常にコンパクトで、連続した値を持つ必要はありません。
-
効率的 — グローバルでの処理 (挿入、更新、削除、走査、検索) はすべて、最高のパフォーマンスと並行処理のために高度に最適化されています。他にも、特定の操作に対応するためのコマンドがあります (データの一括挿入など)。また、記録のソートなど一時的なデータ構造のための特別仕様グローバルもあります。
-
信頼性 — InterSystems IRIS データベースは、論理レベルのジャーナリング、物理レベルのジャーナリングなど、グローバル内に格納されたデータの信頼性を確保するさまざまなメカニズムを備えています。グローバル内に格納されるデータは、データベースのバックアップ操作が実行されるときにバックアップされます。
-
分散型 — InterSystems IRIS では、グローバル内に格納されたデータの物理位置をさまざまな方法で制御することができます。グローバルの格納に使用する物理データベースを定義し、複数のデータベースにグローバルの一部を配布できます。InterSystems IRIS の分散型データベース機能を使用することで、データベースおよびアプリケーション・サーバ・システムのネットワーク全体でグローバルを共有することができます。また、ミラーリング・テクノロジにより、システムのグローバル内に格納されたデータを、他のシステムに自動的に複製することができます。
-
並行処理 — グローバルは、複数プロセス間の同時アクセスをサポートします。個別ノード (配列要素) 内の値の設定と取得は常にアトミックです。信頼性のある同時アクセスを保証するためのロックは必要ありません。また、InterSystems IRIS は強力なロック操作をサポートしており、複数のノードなど、より複雑な状況で並行処理を行うために使用できます。オブジェクトや SQL アクセス使用の際、この並行処理は自動的に実行されます。
-
トランザクション — InterSystems IRIS はトランザクションの境界を指定するコマンドを提供しているので、これを使用するとトランザクションの開始、実行、ロールバックなどが可能です。ロールバックの際、トランザクション内でのグローバルの変更をすべて取り消し、データベースのコンテンツをトランザクション以前の状態にリストアします。InterSystems IRIS のさまざまなロック操作をトランザクションと併用することで、グローバルを使用して従来の ACID トランザクションを実行できます(ACID トランザクションは、アトミック性、一貫性、分離性、持続性を提供します)。オブジェクトや SQL アクセス使用の際、トランザクションは自動的に処理されます。
このドキュメントで説明するグローバルを、別のタイプの InterSystems IRIS 変数配列であるプロセス・プライベート・グローバルと混同しないようにしてください。プロセス・プライベート・グローバルは永続的ではありません。これを作成したプロセスの間のみ維持されます。プロセス・プライベート・グローバルは並行でもありません。これを作成したプロセスからのみアクセスできます。複数文字の名前の接頭語、^|| または ^|"^"| により、プロセス・プライベート・グローバルはグローバルと簡単に区別できます。
例
グローバルの容易性とパフォーマンスは、簡単な例を取り上げるとわかります。以下のプログラムは、10,000 個のノードの配列を生成 (既存ノードは先に削除) し、データベースに保存します。グローバルのパフォーマンスを実感するために試してみてください。
永続配列の生成
Set start = $ZH // get current time
Kill ^Test.Global
For i = 1:1:10000 {
Set ^Test.Global(i) = i
}
Set elap = $ZH - start // get elapsed time
Write "Time (seconds): ",elap
配列内の値を繰り返し処理して読み取るまでに、どのくらいの時間がかかるのか見てください (まず上記例を実行して、配列を構築してください)。
永続配列の読み取り
Set start = $ZH // get current time
Set total = 0
Set count = 0
// get key and value for first node
Set i = $Order(^Test.Global(""),1,data)
While (i '= "") {
Set count = count + 1
Set total = total + data
// get key and value for next node
Set i = $Order(^Test.Global(i),1,data)
}
Set elap = $ZH - start // get elapsed time
Write "Nodes: ",count,!
Write "Total: ",total,!
Write "Time (seconds): ",elap,!
アプリケーションの使用法
InterSystems IRIS アプリケーションでは、さまざまな方法でグローバルを使用します。以下はその例です。
-
オブジェクト、および SQL エンジンに共有される基本ストレージ・メカニズムとしての使用。
-
オブジェクトおよび SQL データに対するビットマップ・インデックスなど、多様なインデックスを提供するメカニズムとしての使用。
-
プロセス・メモリに収まらない可能性のある操作を実行するためのワーク・スペースとしての使用。例えば、用途に合った既存のインデックスがない場合、SQL エンジンはデータをソートするために一時的なグローバルを使用します。
-
オブジェクトおよび SQL アクセスという点で、表現が困難もしくは非効率的な永続オブジェクトまたは SQL テーブルでの特別なオペレーションを実行するため。例えば、メソッド (あるいはストアド・プロシージャや Web メソッド) を指定して、テーブルの保持データについて特別なデータ分析を行うことが可能です。メソッドを使用することで、そのような操作は完全にカプセル化され、呼び出し側は単にメソッドを呼び出すだけで済みます。
-
アプリケーションに特化したカスタマイズされたストレージ構造を実装するため。リレーショナル形式で表現することが難しいデータの保存を必要とするアプリケーションが数多く存在します。グローバルでカスタム構造を指定し、外部クライアントがその構造をオブジェクト・メソッド経由で利用できるようにします。
-
構成データ、クラス定義、エラー・メッセージ、実行可能なコードなど、InterSystems IRIS システムで使用される特別な目的を持った多様なデータ構造のため。
グローバルは、リレーショナル・モデルの範囲に限定されません。特定のアプリケーションを最大限に利用するカスタマイズされた構造を自由に開発できます。多くのアプリケーションでグローバルを賢明に使用することにより、リレーショナル・アプリケーション開発者達が待ち望んだパフォーマンスを提供することができます。
アプリケーションでグローバルを直接使用するかどうかにかかわらず、その動作を理解しておくと役に立ちます。グローバルとその性能を理解することは、アプリケーションの最適な配置構成を決定するうえで役立つのはもとより、さらに効率的なアプリケーションを設計する際にも役立ちます。