ダイアグラムは、ただ単純にテーブル同士を関連付けたものではなく、関連付けたテーブルに結合方向と参照整合性制約を設定してその定義を保存し、ビューやクエリファイル、アプリケーションのSQLなどでそれらのテーブルを利用したときに影響を及ぼす機能です。
- 結合方向 -
結合方向については既に説明しましたが、一応おさらいしておきましょう。
テーブルを関連付ける場合、一方のフィールドの値ともう一方のフィールドの値が一致するレコードが抽出対象となる「等結合」が一般的で、これは内部結合の一形態です。その他に、一方のテーブルのフィールドをすべて抽出し、フィールドの値が一致しないもう一方のテーブルのフィールドは値がNULLとなる外部結合があります。
外部結合には、SQLでテーブルを記述する順序によって左外部結合、右外部結合、完全外部結合の3種類がありますが、これはSQLの記述による表現方法の違いであって、データベースの動作には関係ありません(テーブルの記述順を左右逆にすれば、左外部結合が右外部結合に変わります)。
これらについては、本コラムの第12回「テーブルの関連付け(2)~内部結合と外部結合」で詳しく説明したので、そちらを参照してください。
複雑な上に何度も利用される関連付けでは、アプリケーションの側で逐一結合方向を気にしてSQLを書くより、予めダイアグラムで設定しておいた方が楽です。
- 参照整合性制約 -
ダイアグラムの最も重要な機能が、参照整合性制約の設定です。結合方向だけならSQLでも記述できますが、参照整合性制約はレコードやフィールドを書き換えた場合に、関連付けられたもう一方のテーブルの変更をどのように制御するか──という決まりであり、SQLでは定義できません。
関連付けた2つのテーブルのうち、処理上の基準として着目するテーブルが「参照側」、そこから条件に合致するレコードを引き出す対象となるテーブルが「被参照側」と呼ばれます。
この「参照/被参照」の関係の安定が保たれるのは、双方のテーブルの内容に矛盾がない場合だけです。漫然と処理を進めていくと、
(a) |
被参照側に存在しているにもかかわらず
参照側のテーブルからはまったく参照されないレコード
(取り残されてしまった迷子のレコード)
|
が存在したり、
|
(b) |
参照関係は成立しているけれど
双方の値が噛み合っていない状態
(存在しないレコードを指し示すフィールド)
|
が生じてしまうなど、様々な矛盾が生じてきます。 |
- (a)レコードが存在しない矛盾 -
商品マスターからある商品が削除された場合、リレーションを設定された在庫テーブル内の該当する商品の在庫数は「参照元が消えてしまうため無意味」になってしまいます。
また、仕入先テーブルの仕入先が存在しなくなれば、その仕入先から仕入れている商品(商品テーブルの仕入先フィールドに該当する仕入先のIDが記録されているレコード)も存在しなくなるのが普通です。
商品が消えれば在庫が、仕入先が消えれば商品が……という具合に、一方のテーブルでレコードが削除された場合には、もう一方のテーブルのレコードも削除しなければデータベース内に矛盾が生じます。
- (b)IDフィールドの変更による矛盾 -
商品の販売(受注)を記録するテーブルでは、顧客マスターと商品マスターにリレーションを設定し、「誰に(顧客)何を(商品)販売したか」が明らかにされます。
もし、取引が完結していない(受注が確定していない)段階で、顧客マスターから顧客を識別するお客様IDが変更されたり、商品マスターから商品を識別する商品IDが変更されたりしたらどうでしょう?
販売(受注)を記録するテーブルには、「存在しないID」または「他の顧客や商品を指し示すID」が記録された状態になってしまいます。こういったことは滅多に発生しませんが、あり得ないことでもありません。
- 矛盾を自動的に回避する -
上述の問題のうちレコードの削除による矛盾なら、アプリケーションの側でSQLを発行して逐一解決することもできなくはありません。例えば、あるレコードを削除するSQLを発行してそれが成功したら、関連するテーブルの該当レコードを探し出してそれを削除するSQLを発行する──といった具合です。
しかし、たくさんのテーブルの関係を把握し、矛盾が生じるたびに訂正処理を行っていては大変です。実際にはほとんど不可能であるか、恐ろしく煩雑になってどこかで処理の記述を間違ってしまうことになるでしょう。
販売(受注)を記録する処理では、マスター側(被参照側)のIDフィールドの値が書き換えられた場合に人力でこの矛盾を解決するのはまず不可能でしょう。
こういった矛盾を自動的に解決する機能が「参照整合性制約」です。参照整合性制約には「連鎖削除」と「連鎖更新」の2種類があります。
・ |
連鎖削除
先述した在庫数の問題のように、テーブルからレコードが削除されれば、それを参照している別のテーブルのレコードも自動的に削除されます。これは、レコードに対する制約で、SQL Serverでは「関連レコードの連鎖削除」と表記されています。
|
・ |
連鎖更新
先述した販売記録の問題のように、被参照側テーブルのIDフィールドの値が更新(変更)されれば、それを参照している別のテーブルのフィールドの値も自動的に更新されます。これはフィールドに対する制約で、SQL Serverでは「関連フィールドの連鎖更新」と表記されています。 |
|
|
|