コレクション・プロパティのストレージと SQL プロジェクション
ここでは、リスト・プロパティと配列プロパティが既定で格納される方法と既定で SQL に投影される方法、およびこれらの詳細を変更する方法について説明します。
リスト・プロパティの既定のストレージとプロジェクション
既定では、リスト・プロパティはそれが属するオブジェクトと同じテーブルに格納され、複数の値を含む %ListOpens in a new tab 構造で構成される単一の列として SQL に投影されます。この列内の項目を検索するには、FOR SOME %ELEMENT 述語を使用します。例えば、以下のクエリは、FavoriteColors 列 (FavoriteColors リスト・プロパティのプロジェクション) に要素 'Red' が含まれる行を返します。
SELECT * FROM Sample.Person
WHERE FOR SOME %ELEMENT (FavoriteColors) (%VALUE = 'Red')
または、%INLIST 述語を使用して、リスト内の特定の要素を検索したり、特定の要素が含まれないリストを検索したりすることもできます。例えば、以下のクエリは、FavoriteColors 列にリスト要素 'Red' が含まれない行を返します。
SELECT * FROM Sample.Person
WHERE NOT ('Red' %INLIST (FavoriteColors))
特定のインスタンスのリストが何も要素を含まない場合、これは空文字列として投影されます (SQL NULL 文字列ではありません)。
配列プロパティの既定のストレージとプロジェクション
既定では、配列プロパティは子テーブルに格納され、子テーブルとして投影されます。この子テーブルは親テーブルと同じパッケージ内に存在します。この子テーブルの名前は、以下のようになります。
tablename_fieldname
以下はその説明です。
-
tablename は親クラスの SqlTableName です (指定されている場合)。SqlTableName が指定されていない場合、親クラスの短い名前になります。
-
fieldname は、配列プロパティの SqlFieldName です (指定されている場合)。SqlTableName が指定されていない場合、配列プロパティの名前になります。
例えば、Siblings という名前の配列プロパティが設定された Person クラスがあるとします。Siblings プロパティのプロジェクションは、Person_Siblings という名前の子テーブルです。
この子テーブルには、以下の列が含まれます。
-
親クラスの対応するインスタンスの ID が含まれる列。この列は、配列が含まれる親クラスの外部キーとして機能し、そのクラスに対応する名前が付けられます。投影される Person_Child テーブルでは、この列の名前は Person です。
-
各配列メンバの ID が含まれる element_key という名前の列。
-
各配列メンバの値が含まれる列。この列には、配列プロパティに対応する名前が付けられます。投影される Person_Child テーブルでは、この列の名前は Siblings です。
以下の表は、サンプル・エントリと、Siblings 子テーブルの生成された列名を示しています。
Person | element_key | Siblings |
---|---|---|
10 | C | Claudia |
10 | T | Tom |
12 | B | Bobby |
12 | C | Cindy |
12 | G | Greg |
12 | M | Marsha |
12 | P | Peter |
上の例で ID = 11 のインスタンスのように、親クラスのインスタンスが、空のコレクション (何も要素を含まないコレクション) を保持する場合、そのインスタンスの ID は子テーブルに表示されません。
親テーブルには、Siblings 列は含まれません。
配列メンバを含む列の数とコンテンツは、配列の種類によって異なります。
-
データ型プロパティの配列は、1 列のデータとして投影されます。
-
参照プロパティの配列は、1 列のオブジェクト参照として投影されます。
-
埋め込みオブジェクトの配列は、子テーブル内の複数列として投影されます。これらの列の構造については、"埋め込みオブジェクト・プロパティ" を参照してください。
また、各インスタンスの ID と各配列メンバの識別子は、子テーブルの一意のインデックスを構成します。親インスタンスが関連する配列を持っていない場合、子テーブルには関連するエントリがありません。
既定では、シリアル・オブジェクト・プロパティは、同じ方法で SQL に投影されます。
コレクション・プロパティが配列として投影される際には、プロパティに追加する可能性がある任意のインデックスに対して固有の要件があります。"コレクションのインデックス作成" を参照してください。InterSystems IRIS 永続クラスのインデックスの概要は、"永続クラスのその他のオプション" を参照してください。
配列コレクションによって投影された子テーブルの SQL トリガはサポートされていません。ただし、配列プロパティを更新した後、ObjectScript を使用して親オブジェクトを保存すると、該当するトリガが起動します。
コレクション・プロパティのストレージの制御
リスト・プロパティは子テーブルとして格納できます。また、配列プロパティは $LIST として格納できます。どちらの場合も、そのプロパティの STORAGEDEFAULT パラメータを指定します。
-
リスト・プロパティの場合、既定では、STORAGEDEFAULT が "list" になります。STORAGEDEFAULT に "array" を指定すると、そのプロパティは子テーブルとして格納および投影されます。以下に例を示します。
Property MyList as list of %String (STORAGEDEFAULT="array");
結果のプロジェクションの詳細は、"配列プロパティの既定のストレージとプロジェクション" を参照してください。
-
配列プロパティの場合、既定では、STORAGEDEFAULT が "array" になります。STORAGEDEFAULT に "list" を指定すると、そのプロパティはリストとして格納および投影されます。以下に例を示します。
Property MyArray as array of %String (STORAGEDEFAULT="list");
結果のプロジェクションの詳細は、"リスト・プロパティの既定のストレージとプロジェクション" を参照してください。
STORAGEDEFAULT プロパティ・パラメータは、コンパイラがクラスのストレージを生成する方法に影響します。クラス定義に指定のプロパティのストレージ定義が含まれていた場合、このプロパティ・パラメータはコンパイラによって無視されます。
SQL プロジェクションの制御
コレクション・プロパティが実際に格納される方法に関係なく、プロパティは親テーブル内の列として、子テーブルとして、またはその両方の方法で投影できます (リリース 2022.1 現在、これはリスト・プロパティと配列プロパティの両方に当てはまります)。これを制御するには、そのプロパティの SQLPROJECTION パラメータを指定します。このパラメータには、以下のいずれかの値を指定できます。
-
"column" — このプロパティを列として投影します。
-
"table" — このプロパティを子テーブルとして投影します。
-
"table/column" — このプロパティを列および子テーブルとして投影します。
例えば、以下のクラス定義について考えてみます。
Class Sample.Sample Extends %Persistent
{
Property Property1 As %String;
Property Property2 as array of %String(SQLPROJECTION = "table/column");
}
この場合、システムは、クラスで 2 つのテーブル (Sample.Sample および Sample.Sample_Property2) を生成します。
テーブル Sample.Sample_Property2 は、既定のシナリオどおり、配列プロパティ Property2 のデータを格納します。ただし既定のシナリオとは異なり、クエリは Sample.Sample テーブル内の Property2 フィールドを参照できます。以下に例を示します。
MYNAMESPACE>>SELECT Property2 FROM Sample.Sample where ID=7
13. SELECT Property2 FROM Sample.Sample where ID=7
Property2
"1 value 12 value 23 value 3"
ただし、SELECT * クエリは、Property2 フィールドを返しません。
MYNAMESPACE>>SELECT * FROM Sample.Sample where ID=7
14. SELECT * FROM Sample.Sample where ID=7
ID Property1
7 abc
投影される子テーブルの名前の制御
コレクション・プロパティが子テーブルとして投影される場合は、そのテーブルの名前を制御できます。そのためには、そのプロパティの SQLTABLENAME パラメータを指定します。以下に例を示します。
Property MyArray as array of %String(SQLTABLENAME = "MyArrayTable");
Property MyList as list of %Integer(SQLTABLENAME = "MyListTable", STORAGEDEFAULT = "array");
SQLTABLENAME パラメータは、プロパティが子テーブルとして投影されていない場合には効果がありません。