Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

外部キー(FOREIGN KEY)

外部キー(FOREIGN KEY)は、テーブルのカラムに対して設定する制約で、多くのRDB(リレーショナルデータベース)が外部キーをサポートしています。

カラムに外部キーを設定すると、制約を設定したカラムには、参照先のテーブルに格納されている値しか格納できないように限定できます。

また、参照先のテーブルからレコードを変更・削除する場合も、外部キーを設定したカラムで使用されている場合は、値が変更できないようになります。

外部キーの利用例

外部キーは、参照される側のテーブルと、外部キーを設定したカラム(参照する側のテーブル)との間でデータの整合性を保つときに用いる制約です。

また、外部キーの設定する時は、「参照される側/する側」の関係を分かりやすく「親テーブル/子テーブル」と呼ぶことが多いようです。

外部キーの利用例として、次のような「従業員テーブル」と「部署マスタ」の間で外部キーを設定する例を見ていきましょう。

参照する側(子テーブル)の部署コードに対し、参照される側(親テーブル)の部署コードを指定して、外部キー(FOREIGN KEY )制約を設定します。

上記のような外部キー(FOREIGN KEY )制約を設定することで、従業員テーブルの部署コードには、部署マスタにある部署コードしか設定できなくなります。
もし、部署マスタに存在しない部署コードを、従業員テーブルに設定してレコードを登録しようとした場合、SQLエラーとなりデータが登録できません。

また、従業員テーブルで使用している部署コードを、親テーブルとなる部署マスタ側で変更しようとした場合に、エラーを表示するか、参照する側の従業員テーブルの部署コードを、変更後の値で一緒に更新するか、NULL値を挿入することができます。

このように、外部キー(FOREIGN KEY )制約を設定することで、2つのテーブル間のデータ整合性がデータベースレベルで保証されるようになり、これらのデータを参照するアプリケーション開発を容易にすることが期待できます。

外部キー(FOREIGN KEY )制約の設定方法

それでは、実際に外部キー(FOREIGN KEY )制約を設定するスクリプトを作成して、テーブルに外部キーを設定し、実際のデータベースの動作を確認してみましょう。

今回は、MySQLデータベース上に、前述の利用例と同じように、「従業員テーブル」と「部署マスタ」を作成し、部署コードに外部キーを設定する例を紹介します。

テーブルを作成

外部キーを設定するためには、当然ながらテーブルが必要です。以下のCREATE TABLEを使用してデータベース上に2つのテーブルを作成し、テスト用のデータも挿入します。

部署マスタを作成するCREATE TABLE文およびテストデータ作成用のINSERT

CREATE TABLE depts (
   dept_cd     char(3),        -- 部署コード
   dept_name   varchar(255),   -- 部署名
   PRIMARY KEY (dept_cd)       -- 主キー(部署コード)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

INSERT INTO depts VALUES('B01', '営業部');
INSERT INTO depts VALUES('B02', '広報部');
INSERT INTO depts VALUES('B03', '人事部');
INSERT INTO depts VALUES('B04', '企画部');

従業員テーブルを作成するCREATE TABLE文およびテストデータ作成用のINSERT

CREATE TABLE employees (
   emp_id     varchar(20),     -- 従業員ID
   emp_name   varchar(255),    -- 氏名
   dept_cd    char(3),         -- 部署コード
   PRIMARY KEY (emp_id)        -- 主キー(従業員ID)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

INSERT INTO employees VALUES('1001', 'YAMADA','B01');
INSERT INTO employees VALUES('1002', 'SUZUKI','B01');
INSERT INTO employees VALUES('1003', 'ITO','B02');
INSERT INTO employees VALUES('1004', 'KATO','B03');

外部キーを設定

テーブルを作成したら、次のALTER文を実行して、従業員テーブルの部署コードから、部署マスタの部署コードを参照する外部キー(FOREIGN KEY )制約を設定しましょう。

ALTER TABLE employees
    ADD FOREIGN KEY
    REFERENCES depts (dept_cd); ---- 部署マスタの部署コードを参照先に設定

外部キーは、CREATE TABLEでテーブルを作成するときに、一緒に作成することもできます。上の外部キーをCREATE TABLEで設定するには、次のように記述します。

CREATE TABLE employees (
   emp_id     varchar(20),     -- 従業員ID
   emp_name   varchar(255),    -- 氏名
   dept_cd    char(3),         -- 部署コード
   PRIMARY KEY (emp_id),        -- 主キー(従業員ID)
   -- ↓ ここで外部キーを指定 ↓ --
   FOREIGN KEY(dept_cd) -- 外部キー
    REFERENCES depts(dept_cd) -- 部署マスタの部署コードを参照先に設定
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

参照される側(親テーブル)に存在しないキーを登録する

外部キー(FOREIGN KEY )制約を設定すると、参照される側(親テーブル)に存在したい値を登録すると、SQLエラーとなり登録できません。

次のINSERT文を実装し、部署マスタに存在しない部署コードを指定して、従業員マスタを登録してみましょう。

INSERT INTO employees VALUES('1005', 'MORI','Z99');

<実行結果>
ERROR 1452 (23000):

このように、INSERT文がエラーとなり、データが登録できません。

同じように、次はUPDATE文を使って、従業員テーブルの部署コードに、部署マスタに存在しない値を設定してみます。

UPDATE employees
SET dept_cd = 'Z99'
WHERE emp_id = '0001';

<実行結果>
ERROR 1452 (23000):

UPDATE文でもエラーとなることが確認できます。

参照される側(親テーブル)のレコードを更新/削除する

次は、参照される側(親テーブル)のレコードを更新/削除した時の動作についてです。

部署マスタのように、参照される側(親テーブル)のレコードを更新または削除しようとした時、その値が参照する側(子テーブル)で使用されている場合、エラーで更新または削除できません。

ただし、外部キーを作成する時に、次のようなreference_optionを指定することにより、その振る舞いを変更させることができます。

ALTER TABLE employees
    ADD FOREIGN KEY
    REFERENCES depts (dept_cd)
    [ON DELETE reference_option]   --レコード削除時の振る舞い
    [ON UPDATE reference_option])  --レコード更新時の振る舞い

reference_optionに指定可能な値は次の通りです。指定を省略した場合はRESTRICT が指定された場合と同じ動きになります。

RESTRICT

子テーブルで使用されている値を、親テーブル側で削除/更新するとエラーになります。指定を省略した場合は RESTRICT がデフォルト値です。

CASCADE

親テーブル側で削除/更新すると、子テーブルにも同じ値を削除または更新します。

SET NULL

親テーブル側で削除/更新すると、子テーブルの同じ値を持つカラムをNULLで更新します。

まとめ

外部キー(FOREIGN KEY)の概要や、作成方法について解説してきました。

外部キーを利用することで、データベースレベルでデータの整合性が保たれるため、アプリケーション側でデータの生合成について考慮が必要なくなり、アプリケーション開発の生産性向上も期待できます。

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。