永続オブジェクトの概要
ここでは、永続クラスを使用した作業時の理解に役立つ概念について説明します。
ここで示されているサンプルの一部は、Samples-Data サンプル (https://github.com/intersystems/Samples-DataOpens in a new tab) からのものです。(例えば) SAMPLES という名前の専用ネームスペースを作成し、そのネームスペースにサンプルをロードすることをお勧めします。 一般的な手順は、"サンプルのダウンロード" を参照してください。
永続クラス
永続クラスとは、%PersistentOpens in a new tab を継承するあらゆるクラスのことです。永続オブジェクトとは、そのようなクラスのインスタンスのことです。
%PersistentOpens in a new tab クラスは、%RegisteredObjectOpens in a new tab のサブクラスであるため、オブジェクト・クラスになります。オブジェクト・インスタンス・メソッドを提供することに加え、%PersistentOpens in a new tab クラスでは、永続インタフェースも定義します。これは、メソッドのセットです。これらのメソッドにより、データベースにオブジェクトを保存すること、データベースからオブジェクトをロードすること、オブジェクトを削除すること、および存在をテストすることができるようになります。
既定の SQL プロジェクションの概要
どのような永続クラスについても、コンパイラが SQL テーブル定義を生成します。この定義により、オブジェクト・インタフェースに加えて、保存されたデータに SQL でアクセスできます。
このテーブルには、保存されたオブジェクトごとに 1 つのレコードが格納されています。また、このテーブルは InterSystems SQL でクエリできます。以下に、Sample.Person テーブルのクエリ結果を示します。
以下のテーブルに、既定のプロジェクションをまとめます。
投影元 (オブジェクト・コンセプト) | 投影先 (リレーショナル・コンセプト) |
---|---|
パッケージ | スキーマ |
クラス | テーブル |
OID | ID フィールド |
データ型プロパティ | フィールド |
参照プロパティ | 参照フィールド |
埋め込みオブジェクト | 一連のフィールド |
リスト・プロパティ | リスト・フィールド |
配列プロパティ | 子テーブル |
ストリーム・プロパティ | BLOB |
インデックス | インデックス |
クラス・メソッド | ストアド・プロシージャ |
他のトピックでは、詳細情報を示し、変更可能な内容について説明します。
-
テーブル名と、そのテーブルが属するスキーマの名前の詳細は、"永続クラスの定義" を参照してください。
同じトピックでは、サブクラスのプロジェクションを制御する方法についても説明しています。
-
リテラル・プロパティのプロジェクションについての詳細は、"リテラル・プロパティの定義と使用" を参照してください。
-
コレクション・プロパティのプロジェクションについての詳細は、"コレクション・プロパティのストレージと SQL プロジェクション" を参照してください。
-
ストリーム・プロパティのプロジェクションについての詳細は、"ストリームを使用した作業" を参照してください。
-
オブジェクト値プロパティのプロジェクションについての詳細は、"オブジェクト値プロパティの定義と使用" を参照してください。
-
リレーションシップのプロジェクションについての詳細は、"リレーションシップの定義と使用" を参照してください。
保存したオブジェクトの識別子 : ID および OID
初めてオブジェクトを保存するとき、システムは、2 つの永続識別子を作成します。どちらの識別子も保存したオブジェクトに後でアクセスする場合や、保存したオブジェクトを削除する場合に使用できます。最も広範に使用される識別子は、オブジェクト ID です。ID は、テーブル内で一意である単純なリテラル値です。既定では、システムは ID として使用する整数を生成します。
OID は、より一般的です。OID にはクラス名も含まれていて、データベース内で一意です。実際には、アプリケーションは OID 値を使用する必要はありません。ID 値で十分に機能します。
%PersistentOpens in a new tab クラスには、ID または OID を使用するメソッドがあります。ID は、%OpenId()、%ExistsId()、%DeleteId() などのメソッドを使用するときに指定します。OID は、%Open()、%Exists()、%Delete() などのメソッドに引数として指定します。つまり、引数として ID を使用するメソッドは、そのメソッドの名前に Id が含まれているということです。引数として OID を使用するメソッドは、そのメソッドの名前に Id が含まれていません。このようなメソッドは、ほとんど使用されません。
永続オブジェクトがそのデータベースに保存されると、その参照属性 (つまり、他の永続オブジェクトへの参照) の値はすべて OID 値として保存されます。OID を持たないオブジェクト属性については、オブジェクトのリテラル値が、その他のオブジェクト状態と共に保存されます。
オブジェクト ID から SQL へのプロジェクション
オブジェクトの ID は、対応する SQL テーブルで使用できます。可能な場合、InterSystems IRIS は ID というフィールド名を使用します。また、InterSystems IRIS には、どのフィールド名を使用しているかわからない場合でも、ID にアクセスする方法があります。このシステムは、以下のとおりです。
-
オブジェクト ID は、オブジェクトのプロパティではないため、プロパティとは異なる扱いを受けます。
-
ID という名前のプロパティ (どのような大文字小文字の組合せであっても) がクラスに含まれていない場合、テーブルにはフィールド ID も含まれるようになり、そのフィールドにオブジェクト ID が格納されます。この例については、前のセクションを参照してください。
-
ID という名前 (どのような大文字小文字の組合せであっても) を SQL に投影したプロパティがクラスに含まれている場合、テーブルにはフィールド ID1 も含まれるようになり、このフィールドにオブジェクト ID の値が保持されます。
同様に、ID および ID1 として投影されたプロパティがクラスに含まれている場合、テーブルにはフィールド ID2 も含まれるようになり、このフィールドにオブジェクト ID の値が保持されます。
-
すべての場合で、テーブルに疑似フィールド %ID も用意され、オブジェクト ID の値が保持されます。
OID は SQL テーブルでは使用できません。
SQL でのオブジェクト ID
InterSystems IRIS は、ID フィールドに一意性を強制します (実際の名前は、どのようなものであってもかまいません)。また、InterSystems IRIS は、このフィールドの変更を禁止します。つまり、このフィールドに対する SQL UPDATE または INSERT 操作は実行できないということです。例として、新しいレコードをテーブルに追加するために必要な SQL を以下に示します。
INSERT INTO PERSON (FNAME, LNAME)VALUES (:fname, :lname)
この SQL は ID フィールドを参照しません。InterSystems IRIS は、ID フィールドの値を生成し、要求されたレコードの作成時にその値を挿入します。
永続クラスに固有のクラス・メンバ
InterSystems IRIS クラスには、永続クラスでのみ意味のある数種のクラス・メンバを含めることができます。これに該当するものは、ストレージ定義、インデックス、外部キー、およびトリガです。
ストレージ定義
ほとんどの場合 (後述するように)、永続クラスごとにストレージ定義が存在します。ストレージ定義の用途は、グローバル構造を記述することです。InterSystems IRIS では、クラスのデータを保存するときや、クラスの保存データを読み込むときに、この構造を使用します。統合開発環境 (IDE) では、クラス定義の最後の部分にストレージ定義が表示されます。以下は、部分的な例です。
<Storage name="Default">
<Data name="PersonDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>Name</Value>
</Value>
<Value name="3">
<Value>SSN</Value>
</Value>
<Value name="4">
<Value>DOB</Value>
</Value>
<Value name="5">
<Value>Home</Value>
</Value>
<Value name="6">
<Value>Office</Value>
</Value>
<Value name="7">
<Value>Spouse</Value>
</Value>
<Value name="8">
<Value>FavoriteColors</Value>
</Value>
</Data>
<DataLocation>^Sample.PersonD</DataLocation>
<DefaultData>PersonDefaultData</DefaultData>
<ExtentSize>200</ExtentSize>
<IdLocation>^Sample.PersonD</IdLocation>
<IndexLocation>^Sample.PersonI</IndexLocation>
<Property name="%%CLASSNAME">
<Selectivity>50.0000%</Selectivity>
</Property>
...
また、ほとんどの場合、コンパイラでもストレージ定義が生成および更新されます。永続クラスに使用するグローバルの詳細は、"永続オブジェクトとグローバル" を参照してください。
インデックス
その他の SQL テーブルのように、InterSystems SQL テーブルはインデックスOpens in a new tabを保持できます。インデックスを定義するには、対応するクラス定義にインデックス定義を追加します。
インデックスにより、特定のフィールドまたはフィールドの組合せの一意性を確保する制約を追加できます。このようなインデックスの詳細は、"永続クラスの定義" を参照してください。
インデックスのもう 1 つの用途は、クエリの実行速度を速くするために、クラスに関連付けられ頻繁に要求されるデータのソート済み特定サブセットを定義することです。例えば、一般に、特定のフィールドを使用する WHERE 節がクエリに含まれている場合は、そのフィールドにインデックスが作成されていると、クエリの実行速度が速くなります。一方、そのフィールドにインデックスがない場合、エンジンは、すべての行に対して指定の条件と一致しているかどうかを確認するフル・テーブル・スキャンを実行する必要があります。これは、テーブルが巨大になると、負荷の高い操作になります。"永続クラスのその他のオプション" を参照してください。
外部キー
InterSystems SQL テーブルは、外部キーOpens in a new tabも保持できます。これを定義するには、対応するクラス定義に外部キー定義を追加します。
外部キーは、新しいデータが追加された場合や、データが変更された場合に InterSystems IRIS が使用するテーブル間に、参照整合性制約を確立します。リレーションシップを使用すると、システムはリレーションシップを自動的に外部キーとして扱います。リレーションシップを使用しない場合や、追加する理由が別にある場合は、外部キーを追加することもできます。
外部キーの詳細は、"永続クラスのその他のオプション" を参照してください。
トリガ
InterSystems SQL テーブルは、トリガOpens in a new tabも保持できます。これを定義するには、対応するクラス定義にトリガ定義を追加します。
トリガでは、特定のイベントの発生時 (具体的には、レコードの挿入時、変更時または削除時) に自動的に実行されるコードを定義します。
トリガの詳細は、"永続クラスのその他のオプション" を参照してください。
その他のクラス・メンバ
クラス・メソッドやクラス・クエリは、ストアド・プロシージャOpens in a new tabとして呼び出せるように定義できます。このストアド・プロシージャは SQL から呼び出せます。
ここで説明していないクラス・メンバの場合は、SQL への投影がありません。つまり、InterSystems IRIS には、それらのクラス・メンバを SQL から直接使用する方法や、SQL から簡単に使用できるようにする方法がないということです。