データベース設計を勉強していると、必ず出てくる「FOREIGN KEY(外部キー)」という言葉。テーブル間の関係性を定義する重要な機能ですが、初心者にとっては少し難しく感じるかもしれません。
この記事では、MySQL初心者の方でも理解できるように、FOREIGN KEYの基礎から実践的な使い方まで、わかりやすく解説していきます。
FOREIGN KEY(外部キー)とは?
FOREIGN KEY(外部キー)は、あるテーブルのカラムが別のテーブルの主キーを参照することで、2つのテーブル間の関連性を定義する制約です。
簡単に言えば、「このテーブルのこの項目は、あちらのテーブルのデータを参照していますよ」という関係を明示する仕組みです。
身近な例で理解しよう
例えば、オンラインショップを想像してください。
- 顧客テーブル:お客様の情報(ID、名前、メールアドレスなど)
- 注文テーブル:注文情報(注文ID、注文日、商品など)
注文は必ず「誰かのお客様」が行うものですよね。この「誰か」を特定するために、注文テーブルには顧客IDが必要です。この顧客IDが外部キーになります。
なぜFOREIGN KEYが必要なのか?
FOREIGN KEYを使わないと、以下のような問題が発生する可能性があります。
問題例:データの不整合
FOREIGN KEYがない場合、存在しない顧客ID(例:ID=9999)で注文を登録できてしまいます。これでは「誰の注文かわからない」という状態になり、データの信頼性が損なわれます。
-- FOREIGN KEYがない場合、このような不正なデータが入ってしまう
INSERT INTO orders (order_id, customer_id, order_date)
VALUES (1, 9999, '2025-01-01'); -- customer_id=9999は存在しない!
FOREIGN KEYで解決
FOREIGN KEYを設定すると、MySQLが自動的にチェックして、存在しない顧客IDでの注文登録を防いでくれます。
FOREIGN KEYの作り方
実際のSQL文を使って、FOREIGN KEYの設定方法を見ていきましょう。
テーブル作成時に設定する方法
-- 親テーブル(参照される側)
CREATE TABLE customers (
customer_id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(100)
);
-- 子テーブル(参照する側)
CREATE TABLE orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10, 2),
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
既存テーブルに後から追加する方法
ALTER TABLE orders
ADD FOREIGN KEY (customer_id) REFERENCES customers(customer_id);
FOREIGN KEYの構文ポイント
FOREIGN KEY (カラム名):外部キーにするカラムを指定REFERENCES テーブル名(カラム名):参照先のテーブルとカラムを指定- 参照先は必ずPRIMARY KEYまたはUNIQUEキーである必要があります
参照整合性とは?
参照整合性とは、外部キーによって保たれるデータの整合性のことです。
FOREIGN KEYを設定すると、以下のルールが自動的に適用されます。
ルール1:存在しないデータは参照できない
-- 顧客ID=100が存在しない場合、このINSERTはエラーになる
INSERT INTO orders (order_id, customer_id, order_date)
VALUES (1, 100, '2025-01-01');
-- エラー: Cannot add or update a child row: a foreign key constraint fails
ルール2:参照されているデータは簡単に削除できない
-- 注文がある顧客は、デフォルトでは削除できない
DELETE FROM customers WHERE customer_id = 1;
-- エラー: Cannot delete or update a parent row: a foreign key constraint fails
この仕組みによって、データの不整合が防がれます。
CASCADE・SET NULLなどのオプション
親テーブルのデータが更新・削除された場合の動作を、オプションで制御できます。
ON DELETE CASCADE:連鎖削除
顧客を削除したら、その顧客の注文も自動的に削除されます。
CREATE TABLE orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT NOT NULL,
order_date DATE NOT NULL,
FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
ON DELETE CASCADE
);
ON DELETE SET NULL:NULL設定
顧客を削除したら、注文の顧客IDをNULLに設定します。
CREATE TABLE orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT, -- NULLを許可
order_date DATE NOT NULL,
FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
ON DELETE SET NULL
);
ON UPDATE CASCADE:連鎖更新
顧客IDが変更されたら、注文の顧客IDも自動的に更新されます。
FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
ON UPDATE CASCADE
主なオプション一覧
- CASCADE:親の変更に合わせて子も変更
- SET NULL:親が削除されたら子をNULLに
- RESTRICT:参照されている親は変更不可(デフォルト)
- NO ACTION:RESTRICTと同じ動作
FOREIGN KEYの注意点
注意点1:テーブルエンジンの確認
FOREIGN KEYを使用するには、テーブルエンジンがInnoDBである必要があります。
-- テーブルエンジンを確認
SHOW TABLE STATUS WHERE Name = 'orders';
-- InnoDBに変更する場合
ALTER TABLE orders ENGINE = InnoDB;
注意点2:データ型の一致
外部キーと参照先のカラムは、データ型が完全に一致している必要があります。
-- NG:型が一致していない
customer_id INT UNSIGNED -- 親テーブル
customer_id INT -- 子テーブル(エラーになる)
-- OK:型が一致している
customer_id INT -- 親テーブル
customer_id INT -- 子テーブル
注意点3:既存データのチェック
既存テーブルにFOREIGN KEYを追加する場合、既存データが参照整合性を満たしている必要があります。
-- 既存データに不整合がある場合、ALTER TABLEが失敗する
-- まずは不整合データを確認
SELECT * FROM orders
WHERE customer_id NOT IN (SELECT customer_id FROM customers);
注意点4:パフォーマンスへの影響
FOREIGN KEYを設定すると、INSERT・UPDATE・DELETE時に整合性チェックが行われるため、わずかにパフォーマンスが低下する可能性があります。ただし、データの信頼性を考えると、多くの場合でこのコストは許容範囲です。
まとめ
この記事では、MySQLのFOREIGN KEY(外部キー)について解説しました。
重要ポイント
- FOREIGN KEYは、テーブル間の関連性を定義し、データの整合性を保つ制約
- 存在しないデータへの参照を防ぎ、データベースの信頼性を高める
- CASCADE、SET NULLなどのオプションで、連鎖操作を制御できる
- InnoDBエンジンが必須で、データ型の一致にも注意が必要
FOREIGN KEYを適切に使うことで、より堅牢で信頼性の高いデータベース設計が可能になります。最初は難しく感じるかもしれませんが、実際に手を動かして試してみることで、理解が深まるはずです。