言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

  1. トップページ
  2. SQL辞典
  3. PRIMARY KEY / FOREIGN KEY

PRIMARY KEY / FOREIGN KEY

対応: SQL-92(1992)

主キーはテーブルの行を一意に識別する列、外部キーは別テーブルの主キーを参照する列です。テーブル間のリレーションシップを定義します。

構文

主キーを設定します(列定義内)。

列名 データ型 PRIMARY KEY

主キーを設定します(テーブル制約として)。

PRIMARY KEY (列名)

複合主キーを設定します。

PRIMARY KEY (列名1, 列名2)

外部キーを設定します。

FOREIGN KEY (列名) REFERENCES 参照テーブル名 (参照列名)
    ON DELETE アクション
    ON UPDATE アクション

構文一覧

構文概要
PRIMARY KEYテーブルの主キーを設定します。NOT NULLかつUNIQUEが自動的に適用されます。テーブルに1つだけ設定できます。
PRIMARY KEY (列1, 列2)複数列を組み合わせた複合主キーを設定します。中間テーブル(多対多の関係)によく使われます。
FOREIGN KEY...REFERENCES別テーブルの列を参照する外部キーを設定します。外部キーが指す先のデータが必ず存在することを保証する仕組み(参照整合性)を実現します。
ON DELETE CASCADE参照先の行が削除されたとき、参照元の行も自動的に削除します。
ON DELETE SET NULL参照先の行が削除されたとき、外部キー列をNULLに設定します。
ON DELETE RESTRICT参照元に行が存在する場合、参照先の行の削除を禁止します(デフォルト)。
ON UPDATE CASCADE参照先のキー値が変更されたとき、参照元も自動的に更新します。

サンプルコード

以下の『customers』テーブルと『orders』テーブルを例に説明します。

customers customer_id name 1 孫悟空 2 ベジータ 3 ブルマ 3 rows in set

orders order_id customer_id total 1 1 3200 2 1 5800 3 2 1500 3 rows in set

顧客テーブル(参照される側)を作成します。

sample_primary_foreign_key.sql
CREATE TABLE customers (
    customer_id INT          NOT NULL AUTO_INCREMENT,
    name        VARCHAR(100) NOT NULL,
    PRIMARY KEY (customer_id)
);
Query OK, 0 rows affected

テーブル構造を確認します。

sample_primary_foreign_key.sql
DESCRIBE customers;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| customer_id | int          | NO   | PRI | NULL    | auto_increment |
| name        | varchar(100) | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
2 rows in set

注文テーブル(外部キーを持つ側)を作成します。

sample_primary_foreign_key.sql
CREATE TABLE orders (
    order_id    INT  NOT NULL AUTO_INCREMENT,
    customer_id INT  NOT NULL,
    total       INT  NOT NULL,
    PRIMARY KEY (order_id),
    CONSTRAINT fk_orders_customer
        FOREIGN KEY (customer_id)
        REFERENCES customers (customer_id)
        ON DELETE RESTRICT
        ON UPDATE CASCADE
);
Query OK, 0 rows affected

テーブル構造を確認します。customer_id に外部キー(MUL)が設定されています。

sample_primary_foreign_key.sql
DESCRIBE orders;
+-------------+------+------+-----+---------+----------------+
| Field       | Type | Null | Key | Default | Extra          |
+-------------+------+------+-----+---------+----------------+
| order_id    | int  | NO   | PRI | NULL    | auto_increment |
| customer_id | int  | NO   | MUL | NULL    |                |
| total       | int  | NO   |     | NULL    |                |
+-------------+------+------+-----+---------+----------------+
3 rows in set

複合主キーを使った中間テーブル(多対多)を作成します。

※ 以下の例では『products』テーブルは別途作成済みとします。

sample_primary_foreign_key.sql
CREATE TABLE order_products (
    order_id   INT NOT NULL,
    product_id INT NOT NULL,
    quantity   INT NOT NULL DEFAULT 1,
    PRIMARY KEY (order_id, product_id),
    FOREIGN KEY (order_id)   REFERENCES orders   (order_id)   ON DELETE CASCADE,
    FOREIGN KEY (product_id) REFERENCES products (product_id) ON DELETE RESTRICT
);
Query OK, 0 rows affected

実行結果

外部キー制約に違反した INSERT を行った場合のエラー例(MySQL)です。

-- ERROR 1452 (23000): Cannot add or update a child row:
-- a foreign key constraint fails (`shop`.`orders`, CONSTRAINT `fk_orders_customer`
-- FOREIGN KEY (`customer_id`) REFERENCES `customers` (`customer_id`))

ON DELETE RESTRICT の場合、参照されている行を削除しようとした場合のエラー例です。

-- ERROR 1451 (23000): Cannot delete or update a parent row:
-- a foreign key constraint fails

データベース別の書き方

『PRIMARY KEY』と『FOREIGN KEY』の基本構文は主要なデータベースで共通して使用できます。

CREATE TABLE orders (
    order_id    INT NOT NULL,
    customer_id INT NOT NULL,
    PRIMARY KEY (order_id),
    FOREIGN KEY (customer_id) REFERENCES customers (customer_id)
        ON DELETE RESTRICT
        ON UPDATE CASCADE
);

自動連番の主キー定義はデータベースによって異なります。MySQL は『AUTO_INCREMENT』、PostgreSQL は『SERIAL』、SQLite は『INTEGER PRIMARY KEY』を使用します。

-- MySQL
order_id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (order_id)

-- PostgreSQL
order_id SERIAL PRIMARY KEY

-- SQLite
order_id INTEGER PRIMARY KEY

『ON DELETE』『ON UPDATE』のアクション(『CASCADE』『SET NULL』『RESTRICT』)は主要なデータベースで共通して使用できます。ただし、SQLite では外部キー制約がデフォルトで無効になっており、『PRAGMA foreign_keys = ON;』で有効化する必要があります。

-- SQLite(外部キー制約を有効にする)
PRAGMA foreign_keys = ON;

概要

『PRIMARY KEY』は行を一意に識別するための列です。一般的には整数の連番(AUTO_INCREMENT)を使いますが、メールアドレスや商品コードのような自然キーを使う場合もあります。複合主キーは複数列の組み合わせで一意性を保証します。

『FOREIGN KEY』を設定すると、参照先に存在しない値を外部キー列に登録しようとした際にエラーになります。外部キーが指す先のデータが必ず存在することを保証する仕組みを参照整合性といいます。『ON DELETE CASCADE』を使うと、親レコードを削除すると子レコードが自動的に削除されるため、手動でのクリーンアップが不要になります。

テーブル作成の基本は『CREATE TABLE』を、その他の列制約については『NOT NULL / UNIQUE / DEFAULT』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。