参照整合性の設定
参照整合性の構造について
参照整合性(RI)は、データベースに作成することのできる抑制と均衡のシステムであり、これによって、関連付けられたデータがあるテーブル同士を確実に同期させます。
参照整合性(RI)の概念
参照整合性(RI)を使用すると、同一のフィールド値がそのテーブルまたはほかのテーブルに存在するかどうかに基づき、データの変更または、変更や追加や削除の禁止を行うことができます。
定義
参照整合性についての理解は、規則の概念、主キー、外部キー、カスケード規則、および制限規則を理解することにかかっています。このトピックではこれらの定義を説明します。
規則
規則は、原因とその効果の単純なステートメントで、データベースに定義された RI システムによって実行されます。
例 A
たとえば、削除規則によって、主キーを持つレコードが削除されたときに、外部キーを持つレコードに何が起きるかが次のように定義されているとします。「'Bhargava Building' を含むレコードが削除されたとき、そのレコードを参照するテーブル A のすべての行は削除される。」
削除規則は、主キー値を参照する外部キーがある場合、その主キー値を含む行が削除されるのを禁止することもできます。
例 B
更新規則は、ユーザーがレコードを更新またはレコードを追加しようとしたときに、外部キーを含むレコードに何が起こるかを定義したもので、次のようなものです。「ユーザーがテーブル B に新しいレコードを追加しようとしたとき、ビル名がテーブル C に存在しなければ、追加することを拒否する。」
主キー
主キーは規則が従属する 1 つまたは複数の列です。どのテーブルでも主キーは 1 つだけ許可されており、重複値は許可されていません。更新規則では、主キーというのは、レコードの更新または追加が許可されるかどうかを判断するために、更新または追加した列と比較される列のことです。
例 A では、"Bhargava Building" を含む列が主キーです。
例 B では、テーブル C のビル名を含む列が主キーです。
外部キー
外部キーは、処理方法を決定するために主キーと比較される 1 つまたは複数の列です。
前述の
例 A では、テーブル A の "Bhargava Building" を含む列が外部キーです。
前述の
例 B では、テーブル B のビル名を含む列が外部キーです。
カスケード規則
カスケード規則は、データベースがある操作が起こることを許可し、ほかのテーブルまたは行を最初の操作と同期をとるように変更することによって RI を確実にする規則です。たとえば、カスケード削除規則が定義されていると、主キー テーブルでのレコードの削除により、データベースは削除された行の主キーと同じ値の外部キーを持つデータベース中のすべての行を検索して削除します。
制限規則
制限規則は、データベースに既に存在する値に基づく操作を許可するかどうかをデータベースが決定するのに使用する規則です。たとえば、更新制限規則が定義されている場合、外部キーを含む行をテーブルに追加しようとすると、データベース エンジンは外部キー フィールドの値を主キーの値と比較します。同じ値の主キーを持つ行が存在しない場合、その行を外部キー テーブルに追加することは許可されません。
キーおよび規則について
このセクションでは、主キーおよび外部キーの概念についてより詳細に説明します。
表 18 主キーおよび外部キー
テーブル A | テーブル B |
•student_ID | •Name | •stud_ID | •Class |
20543 | John | 20543 | ENG-101 |
20577 | Mary | 20543 | AST-202 |
上記の例では、テーブル A の student_ID(A.student_ID)は IDENTITY データ型で、2 つの行が同じ値を持つことを許可していません。学生はそれぞれユニークな ID 番号を持ちます。student_ID をテーブル A の主キーとして定義します。
それから、テーブル B の stud_ID(B.stud_ID)を A.student_ID を参照する外部キーとして定義します。stud_ID のデータ型は、IDENTITY と比較できる INTEGER などのデータ型である必要があります。主キーと外部キーのデータ型には互換性が必要です。参照整合性を確実にするために、必要なだけの外部キーをいくつでも設定することができます。複数の外部キーは同一の主キーを参照することができます。
主キーを持つテーブルは親テーブルと呼ばれ、外部キーを持つテーブルは子テーブルと呼ばれます。いったんキーが定義されると、表
19 に示すように選択できる動作の範囲が限られます。必要なだけ規則を定義することができますが、タイプごとには 1 つしか定義できません。たとえば、削除制限規則を定義した場合、同じキーにカスケード削除規則を定義することはできません。これは、2 つの動作が相互に排他的であるためです。
表 19 RI 規則の選択
行いたい動作 | 定義する規則 |
B.stud_ID の値が A.student_ID のいずれかの値に一致しなければ、テーブル B に行が追加されたり更新されたりすることを許可しない。 | 更新制限 |
B.stud_ID の値がその行と一致しなければ、テーブル A の行を削除することを許可しない。 | 削除制限 |
テーブル A から行が削除された場合、その削除された A.student_ID の値に一致する B.stud_ID のすべての行をテーブル B から削除する。 | 削除カスケード |
更新制限
前述の例で説明すると、更新制限規則を設定することにより、新規または更新された行の B.stud_ID の値は必ず A.student_ID にも存在していることが保証されます。テーブル B に行を追加できるようにするには、その前に、テーブル A に行があることが必要です。言い方を変えると、子行を作成する前に少なくとも 1 つの親行を作成する必要があります。
削除制限
例では、削除制限規則を設定することにより、テーブル A の行は、テーブル B のいずれかの行がその行を参照している場合は削除できないことが保証されます。Name の値が "John" である行は、John の student_ID がテーブル B で参照されているため、削除できません。
John の student_ID を参照するテーブル B の行がすべて削除されたら、テーブル A から John の行を削除することができます。
削除カスケード
例では、削除カスケード規則を設定することにより、Name 値が "John" の行が削除された場合、テーブル B の両方の行が削除されることを保証します。
PSQL では、自己参照するテーブルに対し、循環するカスケード削除を使用できます。このため、削除カスケードは慎重に使用してください。親テーブル、子テーブル、または両テーブルのすべてのレコードを不用意に削除しないようにしてください。
このようなカスケード削除がどのようにして発生するかをわかりやすくするために例を示します。2 つの列を持つテーブル d3 を作成するとします。
CREATE TABLE d3 (c1 INT PRIMARY KEY, c2 INT)
INSERT INTO d3 VALUES (2,2)
INSERT INTO d3 VALUES (3,2)
INSERT INTO d3 VALUES (1,3)
INSERT INTO d3 VALUES (4,1)
次に、外部キーを追加し、カスケード削除規則を設定するようにテーブルを変更します。
ALTER TABLE d3 ADD FOREIGN KEY (c2) REFERENCES d3 ON DELETE CASCASE
次のステートメントにより、テーブル内のすべての行が削除されます。
DELETE FROM d3 WHERE c1 = 2
c1 = 2 の行だけでなく、すべての行が削除されるのはなぜでしょう?
削除カスケードは、削除された主キーと同じ値の外部キーを持つすべての行を削除します。2 番目の行は最初の行と外部キー関係があります。同様に、3 番目の行は 2 番目の行と、4 番目の行は 3 番目の行と外部キー関係があります。外部キー関係があることで、すべての行に渡ってカスケード削除規則が適用されるため、1 行目により 2 行目が、2 行目により 3 行目が、そして 3 行目により 4 行目が削除されることになります。
PSQL は、相互に参照するテーブルでの循環削除カスケードを許可していません。たとえば、テーブル d1 と d2 があるとして、次のようなシナリオを考えます。
CREATE TABLE d1 (c1 INT PRIMARY KEY, c2 INT)
CREATE TABLE d2 (e1 INT PRIMARY KEY, e2 INT)
次の変更ステートメントは許可されます。
ALTER TABLE d1 ADD FOREIGN KEY (c2) REFERENCES d2 ON DELETE CASCADE
次の変更ステートメントは許可されません。テーブル d1 と d2 には既に削除カスケードの関係があるからです。
ALTER TABLE d2 ADD FOREIGN KEY (e2) REFERENCES d1 ON DELETE CASCADE
主キーの設定
主キーは、SQL ステートメントまたは PSQL Control Center を使用して作成することができます。『
PSQL User's Guide』の
列のタスクを参照してください。
テーブル作成中に主キーを作成する
CREATE TABLE ステートメントで PRIMARY KEY キーワードを使用して、テーブル作成時に主キーを作成することができます。主キーは 1 つまたは複数の列で構成されます。次の例では id が作成され、主キーに指定されることを示しています。
CREATE TABLE mytable (id INTEGER,
myname CHAR(20),
PRIMARY KEY(id))
次の例は複数の列を使ってユニークな値を持つ主キーを作成する方法を示しています。
CREATE TABLE mytable (id INTEGER,
myname CHAR(20),
PRIMARY KEY(id, myname))
主キーに指定した単一または複数の列に UNIQUE 属性を指定したかどうかに関わらず、データベース エンジンはその列に重複値とヌル値を許可しないインデックスを自動的に作成します。どのような場合もキー列にヌル値は許可されません。すべての主キー値はユニークです。
ほかの例については、『SQL Engine Reference』で CREATE TABLE を参照してください。
既存のテーブルに主キーを追加する
PCC を使用して、または ADD PRIMARY KEY を使った ALTER TABLE ステートメントによって、既存のテーブルに主キーを追加することができます。『
PSQL User's Guide』の
列に主キーを設定または削除するには および
SQL Editor を参照してください。
主キーは重複およびヌル値を許可しない列にしか作成することができません。
必要な場合には、列属性を変更し、その列を主キーに設定することを同時に行うことができます。SQL を使った例を示します。
ALTER TABLE mytable MODIFY id INTEGER UNIQUE NOT NULL PRIMARY KEY
複数の列から成る主キーを追加したい場合は、キーを分けて追加する必要があります。
ALTER TABLE mytable ADD PRIMARY KEY(id, myname)
ほかの例については、『
SQL Engine Reference』の
ALTER TABLEを参照してください。
外部キーの設定
外部キーは、SQL ステートメントまたは PSQL Control Center を使用して作成することができます。外部キーを作成するときに、同時に関連する規則も定義できます。同一のキーに複数の規則を定義することができます。関連する規則を指定しないで外部キーを作成した場合、更新と削除はどちらもデフォルトの参照整合性によって制限されます。
テーブル作成中に外部キーを作成する
列の定義で REFERENCES キーワードを使用して、テーブル作成時に外部キーを作成することができます。外部キーは 1 つまたは複数の列で構成されます。列のデータ型は、この外部キーが参照する主キーと同じでなければなりません。次の例では your_id が作成され、mytable.id を参照する外部キーに指定されることを示しています。
CREATE TABLE yourtable (your_id INTEGER REFERENCES mytable(id) ON DELETE CASCADE, yourname CHAR(20))
ステートメントの最後に外部キーの指定を追加することもできます。キーに複数列を使用する場合、この技法を使う必要があります。
CREATE TABLE yourtable (your_id INTEGER,
yourname CHAR(20),
FOREIGN KEY(your_id, yourname) REFERENCES
mytable(id, myname) ON DELETE CASCADE)
外部キーを作成すると、データベース エンジンは指定された列にインデックスを追加します。
ほかの例については、『
SQL Engine Reference』の
CREATE TABLEを参照してください。
既存のテーブルに外部キーを追加する
PCC を使用して、または ADD FOREIGN KEY を使った ALTER TABLE ステートメントによって、既存のテーブルに外部キーを追加することができます。『
PSQL User's Guide』の
外部キーのタスク および
SQL Editor を参照してください。
次の例ではこの外部キーに削除規則と更新規則の 2 つの規則が定義されています。
ALTER TABLE yourtable ADD FOREIGN KEY (your_id,yourname) REFERENCES mytable(id,myname) ON DELETE CASCADE ON UPDATE RESTRICT
DELETE CASCADE は慎重に使用してください。
削除カスケードに記載されている例を参照してください。
ほかの例については、『
SQL Engine Reference』の
ALTER TABLEを参照してください。
Btrieve およびリレーショナル制約間の相互作用
PSQL は、リレーショナル エンジンと MicroKernel エンジンの両方を介して同一データへの同時アクセスをサポートするように設計されていますが、リレーショナル(SQL)データベース アーキテクチャの機能によっては、そのデータへの Btrieve アクセスを妨げるものがあります。たとえば、参照整合性(RI)のようなリレーショナル アクセスを制限するように設計された機能は、データ整合性という点では Btrieve アクセスも制限します。
整合性の設定、バウンド データベース、ODBC/SQL セキュリティ、トリガー、参照整合性、およびオーナー ネームなどの機能をトランザクショナル(Btrieve)アプリケーションが使用するデータベースに実装するには、あらかじめこれらの機能について完全に理解している必要があります。ほとんどの場合、両者の長所を生かすデータベース アクセスを得られますが、セキュリティ、参照整合性、およびトリガーはアクセスやオペレーションに制約を設けるため、一部の Btrieve オペレーションは、それらの実装によって制限されたり妨害されたりする場合があります。
整合性の設定、バウンド データベース、セキュリティ、トリガー、または参照整合性を使用している場合には、データまたはファイルへの Btrieve アクセス時、そのデータに設定されている制約に違反すると、Btrieve アクセスが制限されたり完全にアクセスできなくなったりすることがあります。トリガーと RI は主として Btrieve API を介したデータの操作能力を制限します。
セキュリティとオーナー ネームは、適切なアカウント、アクセス権、およびパスワードを持たないデータへのアクセスまたは操作能力を制限する場合があります。これらの機能について考えられるさまざまな組み合わせはたくさんあるので、最も一般的な組み合わせのみを以下に一覧表示します。
表 20 リレーショナル制約と Btrieve アクセス間の相互作用
条件 | 結果 |
DDF の有無 | 整合性の設定 | バウンド データベース | リレーショナル セキュリティの使用 | トリガーの使用 | RI の使用 | Btrieve アクセス可能 | SQL/ODBC アクセス可能 |
No | - | - | - | - | - | Yes | No |
Yes | No | No | No | No | - | Yes | Yes |
Yes | No | No (1) | No | Yes (2) | - | Yes (2) | Yes |
Yes | Yes | No | No | No | No | Yes | Yes |
Yes | Yes | No | Yes | No | No | Yes (3) | Yes (3) |
Yes | Yes | No (1) | Yes | No | Yes | Yes (4) | Yes (3) (4) |
Yes | Yes | No (1) | Yes | Yes (2) | No | Yes (1) | Yes (3) |
Yes | Yes | Yes | No | No | No | Yes | Yes |
Yes | Yes | Yes | Yes | No | No | Yes (3) | Yes (3) |
Yes | Yes | Yes (1) | Yes | No | Yes | Yes (2) (4) | Yes (3) (4) |
Yes | Yes | Yes (1) | Yes | Yes (2) | No | Yes (2) (3) | Yes (3) |
(1)データベースにバウンド データベースが設定されているかどうかに関係なく、データベース エンジンは、データ ファイルにトリガーある場合、外部キーがある場合、あるいは外部キーで参照される主キーがある場合には、自動的にデータ ファイルをバウンドとしてスタンプします。バウンド データベースやファイルの詳細については、
バウンド データベースを参照してください。
(2)テーブルにトリガーを追加すると、Btrieve API はトリガーの実行を引き起こすあらゆるオペレーションについて、そのファイルへのアクセスが妨げられます。トリガーは Btrieve インターフェイスを介したデータベース操作には作用しないため、このロックアウト動作によってデータの一貫性が保持されます。詳細については、
バウンド データベースと整合性の設定を参照してください。
(3)データベースまたはファイルがセキュリティで保護されている場合、ユーザーがそのファイルに対する権限(リレーショナル ユーザー名とパスワード、または有効な Btrieve オーナー ネーム)を持っているのであれば、アクセスは許可されます。セキュリティで保護されたデータベース内にあるがオーナー ネームが設定されていないファイルには、Btrieve ユーザーはアクセスできません。Btrieve オーナー ネームが既に設定されているファイルにリレーショナル セキュリティを最初に設定するとき、Master ユーザーが Btrieve ファイルのオーナー ネームを使ってユーザーにリレーショナル権限を付与する必要があります。詳細については、
PSQL セキュリティを参照してください。
(4)テーブルに参照整合性制約が含まれており、そのデータベースで整合性の設定が有効になっている場合、制約に違反する Btrieve および SQL 操作は共に行えません。このメカニズムにより、アクセス方法に関係なくデータの整合性が保たれます。
バウンド データベースと整合性の設定
名前付きデータベースに[整合性の設定]属性を指定しない場合、データベース エンジンは参照整合性、トリガー、セキュリティ規則のいずれも強制しません。名前付きデータベースに[整合性の設定]属性を指定すると、データのアクセスに使用する方法とは無関係に、MicroKernel は定義済みセキュリティ、参照整合性(RI)およびトリガーを設定できます。MicroKernel は以下のようにこれらの規則を設定します。
•Btrieve ユーザーはリレーショナル セキュリティの制約を受けません。ファイルにオーナー ネームが設定されている場合、それは有効なままです。ファイルにオーナー ネームがない場合、Btrieve ユーザーはリレーショナル セキュリティ制約に関係なくデータにアクセスできます。Btrieve オペレーションは RI やそれ以外のデータベースに定義されているすべての制約に加え、以下に示すトリガー制限の影響を受けます。
•ファイルに制約が存在する場合、Btrieve アクセスは以下のように許可されます。
表 21 Btrieve アクセスの制限-整合性の設定
ファイルの制約 | Btrieve を使ったアクセスで許可されるレベル |
RI 制約の定義あり | ユーザーはデータのアクセス、および RI 制約の範囲内でのオペレーションの実行が可能です。 |
INSERT トリガーの定義あり | 読み取り専用、更新、および削除オペレーションが許可されます。 |
UPDATE トリガーの定義あり | 読み取り専用、挿入、および削除オペレーションが許可されます。 |
DELETE トリガーの定義あり | 読み取り専用、更新、および挿入オペレーションが許可されます。 |
バウンド ファイルに複数の制約が存在する場合、アクセス レベルは最大限の制約または制約の組み合わせに従います。たとえば、ファイルに INSERT トリガーと UPDATE トリガーが定義されている場合、Btrieve ユーザーは読み取り専用および削除アクセスのみが行えます。
「整合性の設定」が直接「バウンド データベース」に関連付けられていません。データベースは整合性の設定なしでバインドされるか、データベースはバインドされずに整合性の設定を設定されます。
バウンド データベース
名前付きデータベースに「バインド」属性を指定した場合、そのデータベースの DDF およびデータ ファイルはほかのデータベースとは関連付けることができません。また、バウンド データ ファイルを、データベース内の複数のテーブル定義と関連付けることもできません。新しいテーブルまたは DDF をバウンド データベースに追加すると、データベース エンジンが自動的に新しいオブジェクトのバインドを行います。この動作により、予測できない動作やデータ整合性を壊すことになる矛盾を防ぎます。たとえば、同じデータベース内の 2 つの異なるテーブル定義に同じデータ ファイルを使用した場合、一方のテーブルに RI 規則を定義し、もう一方には定義しないでおくことができます。この場合、RI 規則を持たないテーブルに行を挿入することは、もう一方のテーブルの RI 規則に違反することになります。データ ファイルと DDF をバインドすることによりこのような矛盾を防ぎます。
DDF および データ ファイルは、個々にバインドできます。データ ファイルにトリガーがある場合、外部キーがある場合、または外部キーで参照される主キーがある場合、データベース エンジンは自動的にそのデータ ファイルをバインド データ ファイルとして特徴付けます。これらのファイルは別のデータベースと共有できず、複数のテーブル定義に関連付けられることもできません。
データ ファイルがバインドされていることは、そのデータ ファイルへの Btrieve アクセスには直接影響しません。ただし、バインドされたファイルには Btrieve アクセスを制限するほかの制約があることがあります。
関連項目
データベースへの「整合性の設定」および「バウンド データベース」設定の使用法については、
[データベースの新規作成]GUI のリファレンスを参照してください。