Standard または Advancedのライセンスで利用可能。
リレーションシップ クラスには、関連元のオブジェクトと関連先のオブジェクトとの関係を定義する複数のプロパティが含まれています。これらのプロパティは、リレーションシップ クラスの作成時に指定します。
- タイプ: シンプルまたはコンポジット
- 関連元クラスと関連先クラス
- 主キーと外部キー
- 基数: リレーションシップは 1 対 1、1 対多、または多対多?
- メッセージを通知する方向 (カスケード更新または削除をカスタマイズする場合に適用)
- 各リレーションの属性を格納するかどうか
- 名前
- ArcMap で関連レコードをナビゲートするときに表示される正方向ラベルと逆方向ラベル
リレーションシップを作成した後は、基数を制御するためのルールを指定することができます。
シンプル リレーションシップとコンポジット リレーションシップ
リレーションシップ クラスを作成する際には、シンプルとコンポジットのどちらかを指定します。
シンプル リレーションシップでは、関連オブジェクトをそれぞれ独立させることができます。たとえば、鉄道ネットワークに信号機が 1 つ以上関連付けられた踏切があるとします。ただし、踏切の存在は信号機に依存せず、踏切のない鉄道ネットワークにも信号機は存在します。
シンプル リレーションシップで関連元オブジェクトを削除すると、対応する関連先オブジェクトの外部キー フィールドの値が NULL に設定されます。この外部キーの振舞いはフィーチャ間の参照整合性を維持するように設計されています。関連元フィーチャが削除されると、外部キーの値によって関連元のフィーチャと関連付けられていた行の関連性が失われ、結果として外部キーの値は不要のものとして NULL に設定されます。外部キーの目的は、関連先オブジェクトと対応する関連元オブジェクトのリレーションシップを維持することだけです。対応する主キーの値を持つ関連元フィーチャがない場合は、外部キーの値を維持する必要がなくなります。後で同じ関連先フィーチャを新規または別個の関連元フィーチャに関連付ける場合は、FK フィールドを NULL から新規の FK 値に更新できます。
関連先オブジェクトを削除しても、対応する関連元オブジェクトの主キーの値への影響はありません。
シンプル リレーションシップの基数は、1 対 1、1 対多、または多対多のいずれかになります。
シンプル リレーションシップと同様に、コンポジット リレーションシップでもオブジェクトの削除時に参照整合性が維持されますが、その方法は異なります。コンポジット リレーションシップでは、関連先オブジェクトの存在は関連元オブジェクトに依存するため、関連元オブジェクトが削除されると、関連先オブジェクトも削除されます。このプロセスはカスケード削除と呼ばれます。
コンポジット リレーションシップは、フィーチャの空間的な維持にも利用できます。関連元フィーチャを移動または回転すると、メッセージが正方向に設定されていれば、それに合わせて関連先オブジェクトも移動または回転します。
コンポジット リレーションシップは常に 1 対多ですが、リレーションシップ ルールにより 1 対 1 に制限することも可能です。
関連元クラスと関連先クラス
リレーションシップ クラスを作成する際には、関連元となるクラスと関連先となるクラスを選択します。ここで 2 つを取り違えないことが重要となります。コンポジット リレーションシップでカスケード削除が適用されることを考えれば、その重要性は明らかです。
シンプル リレーションシップでは、これを正確に行うことが不可欠です。これは、関連元クラスでレコードを削除すると、シンプル リレーションシップ クラスが関連先クラスで対応するレコードを検索し、そのキー フィールドの値を NULL に設定するためです。関連元クラスの選択を誤った場合、関連元クラスを削除すると、外部キー フィールドでエラーが発生します。次の例は、これがどのように発生するのかを示しています。
ケース 1: Parcel (土地区画) から Zone (土地利用) へのリレーションシップ (正しくない)
これは一般的なエラーです。Zone テーブルにはさまざまなゾーン コードの説明が含まれており、概念的にはルックアップ テーブルに似ています。この場合は、Parcel クラスが関連元、Zone テーブルが関連先です。問題は、Percel を削除すると、Zone テーブルの対応するレコードのキー フィールド (Zone) の値が NULL に設定され、ゾーン コードを持つ他の Perce が Zone テーブルのレコードと一致しなくなることです。
ケース 2: Zone (土地利用) から Parcel (土地区画) へのリレーションシップ (正しい)
この問題を修正するために、Zone テーブルを関連元として設定します。Percel (関連先オブジェクト) を削除しても、Zone テーブルが影響を受けることはありません。ゾーン コード (関連元オブジェクト) を削除すると、Parcel クラスの対応するレコードの Zone フィールドが Zone テーブルのレコードと一致しなくなるので、単にその値が NULL に設定されます。
主キーと外部キー
リレーションシップ クラスでは、関連元オブジェクトと関連先オブジェクトはそれらのキー フィールドの値を通じて対応付けられます。次の例では、Parcel 789 が同じ Percel_ID を持つ Permits2 および 3 と一致します。
リレーションシップの関連元クラスのキー フィールドは主キーと呼ばれ、多くの場合は PK という略語で示されます。正式な主キーとは異なり、リレーションシップの主キー フィールドの値は、すべてのオブジェクトで一意である必要はありません。
関連先クラスのキー フィールドは外部キーと呼ばれ、多くの場合は FK という略語で示されます。外部キーには、関連元クラスの主キーの値と一致する値が含まれています。この場合も、キー フィールドの値がすべての行で一意である必要はありません。
キー フィールドの名前は異なっていてもかまいませんが、同じデータ タイプでなければならず、Percel ID といった同じ種類の情報を含んでいなければなりません。BLOB、日付、ラスターを除くすべてのデータ タイプのフィールドをキー フィールドとして使用することができます。キー フィールドは、リレーションシップ クラスの作成時に指定します。
主キー フィールドを決定する方法の 1 つは、RowID フィールドを使用することです。通常、このフィールドには ObjectID という名前が付いています。ObjectID フィールドは、フィーチャクラスまたはテーブルの作成、またはエンタープライズ ジオデータベースのレイヤーまたはテーブルの登録時に、ArcGIS によって自動的に追加されます。このフィールドは、すべてのレコードで一意な ID を保証します。このフィールドは ArcGIS によって管理されるため、変更することはできません。
特定のオブジェクトの ObjectID フィールドの値は、関連元クラスに存在する間は変化しません。また、オブジェクトがフィーチャである場合、ObjectID フィールドは分割されません。フィーチャを分割すると、元のフィーチャは維持され (ただし、ジオメトリは更新される)、新しいフィーチャが作成されて新しい ObjectID が割り当てられます。この結果、元の ObjectID をもつフィーチャのみが、その ObjectID 値に依存するリレーションシップを維持します。
このため、ObjectID フィールドを使用するよりも、独自の主キー フィールドを作成して使用するほうが適しています。次に、これらの操作を実行する際に、独自に作成した主キー フィールドがリレーションシップの維持にどのように役立つかについて説明します。
- レコードを別のフィーチャクラスまたはテーブルにインポートすると、新しい ObjectID 値が割り当てられ、元の ObjectID 値に依存するリレーションシップは失われます。別の主キーに基づいてリレーションシップを確立すると、レコードをインポートしても主キーの ID 値は変化しません。これにより、一連の関連オブジェクトを新しいクラスにインポートする際に、リレーションを維持することができます。
例外は、コピーと貼り付け機能を使用する場合です。コピーと貼り付けでは ObjectID の値が維持されるため、この方法でのみオブジェクトを移動する予定であれば、ObjectID フィールドを主キーとして使用することができます。
- フィーチャを分割すると、関連元フィーチャは維持され (ジオメトリは更新されます)、新規フィーチャが 1 つ作成されます。元の ObjectID に基づくリレーションシップがある場合は、分割で作成された 2 つのフィーチャのどちらかだけがそのリレーションシップを維持します。ただし、別のフィールドをキーとして使用していた場合は、フィーチャを分割すると、元のフィーチャの ID 値が 2 つの新しいフィーチャにコピーされます。結果として、関連先テーブルのレコードは 2 つの新しいフィーチャに関連付けられることになります。リレーションシップ クラスが多対多として設定されている場合は、理想的な状況です。
フィーチャを分割する計画がなく、関連元クラスですべてのオブジェクトが維持される場合は、ObjectID フィールドをキーとして使用することができます。これを保証できない場合は、ObjectID フィールドを使用するのではなく、独自に ID フィールドを作成して使用するのが最も効果的です。
- 2 つのフィーチャをマージすると、新しいフィーチャは元のフィーチャのどちらかの ObjectID を維持します。フィーチャをマージする予定はあるが、フィーチャクラスからフィーチャを削除したりフィーチャを分割したりする予定はない、という場合は、ObjectID フィールドを主キーとして使用することができます。
基数
リレーションシップの基数は、関連元クラスのオブジェクトの数と関連先クラスのオブジェクトの数を指定します。リレーションシップには、3 つの基数のいずれかを指定することができます。
1 対 1: 1 つの関連元オブジェクトを 1 つの関連先オブジェクトにのみ関連付けることができます。たとえば、土地区画の登記簿は 1 つだけです。ArcGIS では、この基数は多対 1 もカバーします。多対 1 のリレーションシップの例としては、同じ法的な説明に関連する複数の土地区画が挙げられます。
1 対多: 1 つの関連元オブジェクトを複数の関連先オブジェクトに関連付けることができます。たとえば、1 つの土地区画に複数の建物を関連付けることができます。1 対多のリレーションシップでは、1 の側が関連元クラス、多の側が関連先クラスでなければなりません。
多対多: 1 つの関連元オブジェクトを複数の関連先オブジェクトに関連付けることができ、逆に、1 つの関連先オブジェクトを複数の関連元オブジェクトに関連付けることができます。たとえば、1 つの土地が複数の所有者によって所有され、1 人の所有者が複数の土地を所有することがあります。
「1」と「多」は誤解されやすい用語です。1 は、実はゼロ対 1 であり、多は、実はゼロ対多です。したがって、たとえば土地区画と建物の間に 1 対多のリレーションシップを作成した場合、そのリレーションシップでは次のどの状況も有効です。
- 土地区画に建物がない
- 建物はあるが土地区画がない
- 1 つの土地区画に任意数の建物がある
リレーションシップ ルール
リレーションシップ クラスを作成する際には、1 対 1、1 対多、または多対多の基数を指定します。
リレーションシップでは、多くの場合、さらに制限を定義する必要があります。たとえば、土地区画と建物のリレーションシップでは、建物をそれぞれ 1 つの土地区画に関連付けたり、1 つの土地区画に追加できる建物の最大数を設定する必要があります。土地区画に建物を忘れずに関連付け、土地区画に関連付けられる建物の数が多くなりすぎないようにする必要があります。
サブタイプがある場合は、関連先の特定タイプのオブジェクトに関連付けることができる、関連元のオブジェクトの数およびタイプを制限することができます。たとえば、鋼鉄製の電柱はクラス A の変圧器をサポートし、木製の電柱はクラス B の変圧器をサポートすることにします。さらに、有効なサブタイプの組みごとに、有効な基数の範囲を制限する必要もあります。たとえば、鋼鉄性の電柱はクラス A の変圧器を 0 ~ 3 個までサポートでき、木製の電柱ではクラス B の変圧器を 0 ~ 2 個までサポートできることにします。
リレーションシップ クラスのリレーションシップ ルールを表示するには、[カタログ] ウィンドウで該当するリレーションシップ クラスを右クリックし、[リレーションシップ クラス プロパティ] ダイアログ ボックスを開いて [ルール] タブを選択します。
リレーションシップ クラスに関して適用可能なすべてのルールのリストが表示されます。[有効] 列は、どのルールが現在アクティブであるかを示します。
[並べ替え] ドロップダウン メニューで [関連元から関連先サブタイプ] または [関連先から関連元サブタイプ] を選択すると、表示されるリレーションシップ クラスのルールを並べ替えることができます。
リレーションシップ クラスからルールを削除するには、削除するルールを示している行の [有効] チェックボックスをオフにして、[OK] をクリックします。
リレーションシップ クラスに関する新しいルールを作成する手順:
- リレーションシップ クラスに追加するルールを示している行の [有効] チェックボックスをオンにします。
- それぞれ対応するセルに整数を入力して、関連元および関連先のルールに対して適切な [最小] 基数と [最大] 基数を設定します。
- 追加するルールごとに 1 ~ 2 のステップを繰り返します。
- [OK] をクリックします。
リレーションシップ クラスにリレーションシップ ルールを追加すると、そのルールは唯一の有効なリレーションシップとなります。他のリレーションシップおよび基数を有効にするには、さらにリレーションシップ ルールを追加する必要があります。
次の例では、HazMat を 1 ~ 2 つの Deep に関連付けることができ、2 ~ 7 つの Shallow に関連付けることができます。ただし、Sanitary を Deep に関連付けた場合、両者の間にはルールが設定されていないので、[フィーチャの整合チェック] コマンドによってリレーションシップは無効であると判断されます。
メッセージの通知方向
先に説明したように、コンポジット リレーションシップで関連元オブジェクトを削除すると、関連先オブジェクトも自動的に削除されます。
シンプル リレーションシップとコンポジット リレーションシップのどちらを使用するかにかかわらず、操作によっては、あるフィーチャの更新に応じて、その関連フィーチャを更新しなければならないことがあります。さらに、正方向、逆方向、または両方向の更新が要求されることもあります。
- フィーチャを移動または回転する際には、それに合わせて関連フィーチャを移動または回転する必要があります。
- フィーチャを更新する際、関連フィーチャの 1 つの属性を自動的に更新したいことがあります。
- 関連元オブジェクトの更新に応じて、関連先オブジェクトの更新を要求することができます。
- 関連先オブジェクトの更新に応じて、関連元オブジェクトの更新を要求することができます。
この振舞いがリレーションシップに必要な場合は、関連元オブジェクトと関連先オブジェクトに、それらが変更されたことを互いに通知するメッセージを送信させ、関連オブジェクトを適切に更新することができます。
そのためには、リレーションシップの作成時にメッセージの通知方向を設定します。関連元オブジェクトの更新に応じて関連先オブジェクトを更新する必要がある場合は、メッセージの通知方向を「正方向」に設定します。関連先オブジェクトの更新に応じて関連元オブジェクトを更新する必要がある場合は、メッセージの通知方向を「逆方向」に設定します。この両方の更新が必要な場合は、メッセージの通知方向を「両方向」に設定します。リレーションシップを作成したら、メッセージを受信したオブジェクトがそれに応答できるよう、この振舞いをオブジェクトにプログラムする必要があります。
唯一の例外は、コンポジット リレーションシップのメッセージングが「正方向」に設定された場合です。メッセージングが正方向のコンポジット リレーションシップを作成する場合、関連元オブジェクトを移動または回転すると、それに合わせて、関連先オブジェクトが自動的に移動または回転します。リレーションシップを正しくセットアップすれば、この機能はリレーションシップを作成した直後に有効となるため、カスタム プログラミングは必要ありません。
それ以外のメッセージの通知方向では、カスタム プログラミングが必要です。メッセージが正方向のコンポジット リレーションシップを作成する場合、またはカスタム プログラミングを想定している場合を除いて、メッセージの通知は「なし」に設定してください。そうしないと、編集操作を行うたびに必要のないメッセージが生成され、パフォーマンスが低下します。
コンポジット リレーションシップの方向を設定する際には、コンポジット リレーションシップの関連元オブジェクトが削除されると、関連先のすべてのオブジェクトが自動的に削除されることに注意してください。メッセージングをどのように設定したとしても (正方向、逆方向、両方向、なし)、これは避けられません。
方向 | シンプル リレーションシップ | コンポジット リレーションシップ |
---|---|---|
正方向 | カスタム プログラミングを実行していなければ影響はない |
|
逆方向 | カスタム プログラミングを実行していなければ影響はない |
|
両方向 | カスタム プログラミングを実行していなければ影響はない |
|
なし | メッセージの送信を回避すると、パフォーマンスがわずかに向上する |
|
多対多のリレーションシップ
1 対 1 および 1 対多のリレーションシップでは、関連元クラスの主キーの値は、関連先クラスの外部キーの値と直接関連しています。
これに対し、多対多のリレーションシップでは、関連付けをマッピングするために中間テーブルを使用する必要があります。結果として、多対多のリレーションシップを作成すると、中間テーブルが自動的に作成されます。中間テーブルは、関連元の主キーの値を関連先の外部キーの値にマッピングします。各行は、1 つの関連元オブジェクトを 1 つの関連先オブジェクトに関連付けます。
中間テーブルが作成される際には、フィールドだけが自動的に生成されます。ArcGIS は、どの関連元オブジェクトがどの関連先オブジェクトに関連しているのかを認識しないため、テーブル内に行を手動で作成する必要があります。このテーブルの設定は、リレーションシップのセットアップにおいて最も時間のかかる部分です。
リレーションシップ属性
多対多のリレーションシップの中間テーブルは、必要に応じて、もう 1 つの目的でも使用することができます。それは、リレーションシップ自体の属性を格納することです。たとえば、土地区画データベースにおいて、土地区画と所有者の間に、所有者が土地区画を所有し、土地区画が所有者に所有されるというリレーションシップを作成するとします。このリレーションシップの属性として、所有権の割合を指定することができます。このような属性を格納する必要がある場合は、リレーションシップの作成時またはその後に、中間テーブルにそれらを追加することができます。
それほど効果的ではありませんが、1 対 1 または 1 対多のリレーションシップをセットアップする際にも、リレーションシップの属性の格納が必要になることがあります。この場合は、リレーションシップの作成時にそれを指定して、中間テーブルが自動的に作成されるようにする必要があります。多対多のリレーションシップの場合と同様に、中間テーブルは関連元の主キーの値を関連先の外部キーの値にマッピングして、リレーションごとに任意数の属性を格納できるようにします。
リレーションシップ クラスをマップに追加すると、リレーションシップ クラスは開いて操作できるテーブルとして表示されます。ArcGIS は、他の処理に中間テーブルを公開しません。たとえば、[カタログ] ウィンドウで中間テーブルのプロパティを表示して [フィールド] ビューのフィールドを追加/削除したり、中間テーブルでデフォルト値やドメインを使用したりすることはできません。
名前
各リレーションシップ クラスには、[カタログ] ウィンドウに表示される名前が付いています。データベース構造を理解しやすくするために、リレーションシップ クラスにはリレーションシップを説明するような名前を付けてください。
リレーションシップ クラスの名前は、関連元のフィーチャクラスの名前、それに続く Has または Have、最後に関連先フィーチャクラスの名前で構成されます。たとえば、AddressHasZones または ParcelsHaveOwners のようになります。基数が多対 1 または多対多の場合は、関連元のフィーチャクラスの名前を複数形にし、基数が 1 対多または多対多の場合は、関連先のフィーチャクラスの名前を複数形にします。
この命名規則に基づいて、リレーションシップ クラスの基数をその名前から判断することができます。たとえば、両方のフィーチャクラスの名前が複数形である ParcelsHaveOwners は、リレーションシップが多対多であることを示します。
正方向ラベルと逆方向ラベル
正方向ラベルと逆方向ラベルは、 [マップ] ウィンドウ の [属性] ダイアログ ボックスと [個別属性] ダイアログ ボックスに表示され、関連オブジェクトのナビゲーションに役立ちます。
リレーションシップ クラスには、次の 2 つのラベルがあります。
- 関連元から関連先へナビゲートしたときに表示される正方向ラベル。電柱と変圧器の例では、この電柱がこれらの変圧器をサポートすることを意味する「サポート」というラベルを使用できます。
- 関連先から関連元へナビゲートしたときに表示される逆方向ラベル。電柱と変圧器の例では、これらの変圧器がこの電柱に設置されることを意味する「設置される」というラベルを使用できます。