外部キー制約、テーブル間の整合性を保つための制約

ORACLE

テーブルに登録するデータを制限する機能である制約があります。制限したいデータを登録しようとした時にORACLEが自動的にエラーを返してくれるので、使い方次第では便利な機能です。

その中でも、外部キー制約(参照制約・参照整合性制約)について、本記事では解説します。

スポンサーリンク

外部キー制約(参照制約・参照整合性制約)とは

外部キー制約(参照制約・参照整合性制約)とは、あるテーブルの項目値が、参照先のテーブルに存在しない値が登録されるのを許可しないという制約です。関連するテーブル間の整合性を保つための制約ですね。

例えば、受注履歴テーブルの取引先コードに、取引先マスタに存在しない値は登録できないというものです。

実際にそのようなデータを登録しようとするとSQLエラーになります。
ただし、NULLの登録は可能です。

-- テーブル1(参照先テーブル)
A  
---
001
002

-- テーブル2(参照元テーブル)
B   C
--- -

-- ★外部キー制約(テーブル2のBは、テーブル1のAに存在するデータに限る)

-- 参照先テーブルに存在する値をデータ登録
INSERT INTO test_table2 VALUES ('001','z');
⇒ OK

-- 参照先テーブルに存在しない値をデータ登録
INSERT INTO test_table2 VALUES ('003','w');
⇒ ORA-02291: 整合性制約(XXXXX.YYYYY)に違反しました - 親キーがありません
   XXXXX:スキーマ名
   YYYYY:外部キー制約名

-- NULLをデータ登録
INSERT INTO test_table2 VALUES (NULL,'x');
⇒ OK
スポンサーリンク

設定方法

外部キー制約の設定方法は、テーブル作成時や変更時にCONSTRAINT句を指定します。

制約名は、省略可能です。省略時はORACLEが自動的に命名します。

文法(テーブル作成時)

CREATE TABLE 参照元テーブル名
~~
CONSTRAINT 外部キー制約名
FOREIGN KEY (参照元項目名) REFERENCES 参照先テーブル名 (参照先項目名)
オプション
;

文法(テーブル変更時)

ALTER TABLE 参照元テーブル名
ADD CONSTRAINT 外部キー制約名
FOREIGN KEY (参照元項目名) REFERENCES 参照先テーブル名 (参照先項目名)
オプション
;

オプション
オプションは、参照先テーブルのデータ削除時に、参照元テーブルに存在した時の動作を指定します。

指定なし
⇒ ORA-02292: 整合性制約(XXXXX.YYYYY)に違反しました - 子レコードがあります
   XXXXX:スキーマ名
   YYYYY:参照整合性制約名

ON DELETE SET NULL
⇒ 参照元テーブルのデータをNULLに更新する

ON DELETE CASCADE
⇒ 参照元テーブルのレコードを削除する

削除方法

外部キー制約の削除方法は、テーブル変更時にDROP CONSTRAINTを指定します。

また、参照元テーブルのテーブル削除(DROP TABLE)時には、外部キー制約も合わせて削除されます。
参照先テーブルのテーブル削除(DROP TABLE)時には、オプション(CASCADE CONSTRAINTS)をつけることで外部キー制約も合わせて削除されます。オプション指定しない場合は、エラー(ORA-02449)となります。

文法

ALTER TABLE 参照元テーブル名
DROP CONSTRAINT 参照整合性制約名
;

文法(参照先テーブルの削除)

DROP TABLE 参照先テーブル名 CASCADE CONSTRAINTS;

※参照先テーブル名のテーブル削除でオプション(CASCADE CONSTRAINTS)をつけなかった場合
⇒ ORA-02449: 表の一意キーまたは主キーが外部キーに参照されています。

注意点

注意点を以下にまとめました。

  • 参照先項目には、主キーまたは一意キーが張られている必要がある参照先項目には、主キーまたは一意キーが張られている必要がある
  • 参照先テーブルのトランケートはNG
  • 参照先テーブルのテーブル削除はオプション(CASCADE CONSTRAINTS)をつける必要がある
  • 参照元項目へのNULLの登録はOK

まとめ

関連するテーブル間の整合性を保つための制約である外部キー制約について見てきました。

データ登録時や削除時に、自動で整合性チェックをしてくれるので、不整合なデータが絶対に登録されないというメリットがあります。

しかし、その代償として、参照先テーブルのトランケートが出来ないなどの使いにくさもあります。(外部キー制約を事前に削除しておく等の方法はありますが)

外部キーを使用すべきか、またはアプリ側でデータ更新時のチェックを徹底するべきか、よく検討した上で作成するとよいでしょう。
関連


タイトルとURLをコピーしました