第3章 キーと制約

更新日:2025年12月28日

🎧

この章を音声で聴く

再生速度:
本章では、RDBにおけるキーと制約について解説する。キーはタプルを一意に識別するための属性または属性の組み合わせであり、リレーション間の関連付けにも使用される。制約はデータの整合性を保証するためのルールである。主キー、外部キー、候補キー、代理キーといったキーの種類と、一意制約、NOT NULL制約、CHECK制約、参照整合性について説明する。

1. キーの種類

1.1 主キー

主キー(Primary Key)は、リレーション内の各タプルを一意に識別するための属性または属性の組み合わせである。

Table 1. 主キーの特性

特性 説明
一意性 各タプルで異なる値を持つ(重複不可)
非NULL NULL値を含むことができない
最小性 一意性を保証する最小の属性集合
不変性 原則として変更されない(推奨)
-- 主キーの定義例
CREATE TABLE employees (
    employee_id INTEGER PRIMARY KEY,  -- 単一属性の主キー
    name VARCHAR(100) NOT NULL,
    department_id INTEGER
);

-- 複合主キー(複数の属性で構成)
CREATE TABLE order_details (
    order_id INTEGER,
    product_id INTEGER,
    quantity INTEGER NOT NULL,
    PRIMARY KEY (order_id, product_id)  -- 複合主キー
);

1.2 外部キー

外部キー(Foreign Key)は、他のリレーションの主キーを参照する属性である。リレーション間の関連付けを実現し、参照整合性を保証する。

Fig. 1. 外部キーによる参照関係

外部キーによる参照関係
部署テーブル(親)と社員テーブル(子)の参照関係

Table 2. 外部キーの役割

役割 説明
リレーション間の関連付け 親テーブルと子テーブルを結びつける
参照整合性の保証 存在しない値への参照を防止
データの一貫性維持 関連データの整合性を自動的に維持
-- 外部キーの定義例
CREATE TABLE departments (
    department_id INTEGER PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);

CREATE TABLE employees (
    employee_id INTEGER PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    department_id INTEGER,
    FOREIGN KEY (department_id) REFERENCES departments(department_id)
);

-- ON DELETE / ON UPDATE オプション
CREATE TABLE orders (
    order_id INTEGER PRIMARY KEY,
    customer_id INTEGER,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
        ON DELETE SET NULL      -- 親削除時にNULLを設定
        ON UPDATE CASCADE       -- 親更新時に連動更新
);

Table 3. 外部キーの参照アクション

アクション ON DELETE時の動作 ON UPDATE時の動作
CASCADE 参照している行も削除 参照している値も更新
SET NULL 外部キーをNULLに設定 外部キーをNULLに設定
SET DEFAULT 外部キーをデフォルト値に設定 外部キーをデフォルト値に設定
RESTRICT 削除を拒否 更新を拒否
NO ACTION チェック後に拒否(デフォルト) チェック後に拒否(デフォルト)

1.3 候補キー・代理キー

候補キー(Candidate Key):主キーになりうる属性または属性の組み合わせ。一意性と最小性を満たす。

代理キー(Surrogate Key):業務上の意味を持たない人工的なキー。自動採番される連番やUUIDが典型例。

Table 4. キーの種類と特徴

キーの種類 説明
スーパーキー 一意性を満たす属性集合(最小性不要) {社員ID}, {社員ID, 氏名}
候補キー 最小のスーパーキー {社員ID}, {メールアドレス}
主キー 候補キーから選ばれた1つ {社員ID}
代替キー 主キー以外の候補キー {メールアドレス}
外部キー 他テーブルの主キーを参照 {部署ID} → 部署テーブル
自然キー 業務上の意味を持つキー ISBN、マイナンバー
代理キー 人工的に生成したキー AUTO_INCREMENT、UUID
自然キー vs 代理キー
自然キー(ISBN、社会保障番号など)は業務上の意味を持つが、変更される可能性がある。代理キーは変更されないが、業務上の意味がない。実務では、パフォーマンスと安定性から代理キーが推奨されることが多い。

2. 制約

制約(Constraint)は、データの整合性を保証するためのルールである。RDBMSは制約違反を検出し、不正なデータの挿入・更新を防止する。

2.1 一意制約

一意制約(UNIQUE Constraint)は、指定した属性の値が重複しないことを保証する。主キーとは異なり、NULL値を許容する(ただしDBMSにより動作が異なる)。

-- 一意制約の定義
CREATE TABLE users (
    user_id INTEGER PRIMARY KEY,
    email VARCHAR(255) UNIQUE,      -- 単一列の一意制約
    username VARCHAR(50) UNIQUE
);

-- 複合一意制約
CREATE TABLE subscriptions (
    subscription_id INTEGER PRIMARY KEY,
    user_id INTEGER,
    service_id INTEGER,
    UNIQUE (user_id, service_id)    -- 組み合わせで一意
);

2.2 NOT NULL制約

NOT NULL制約は、属性がNULL値を持つことを禁止する。必須項目の入力を強制する際に使用する。

-- NOT NULL制約の定義
CREATE TABLE products (
    product_id INTEGER PRIMARY KEY,
    name VARCHAR(200) NOT NULL,       -- 必須
    price DECIMAL(10,2) NOT NULL,     -- 必須
    description TEXT                   -- 任意(NULLを許容)
);

2.3 CHECK制約

CHECK制約は、属性値が指定した条件を満たすことを保証する。ドメイン(値の範囲)を制限する際に使用する。

-- CHECK制約の定義
CREATE TABLE employees (
    employee_id INTEGER PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    age INTEGER CHECK (age >= 18 AND age <= 120),
    salary DECIMAL(10,2) CHECK (salary >= 0),
    gender CHAR(1) CHECK (gender IN ('M', 'F', 'O')),
    hire_date DATE CHECK (hire_date >= '1900-01-01')
);

-- 複数列を参照するCHECK制約
CREATE TABLE contracts (
    contract_id INTEGER PRIMARY KEY,
    start_date DATE NOT NULL,
    end_date DATE NOT NULL,
    CHECK (end_date > start_date)   -- 終了日は開始日より後
);

Table 5. 制約の種類まとめ

制約 目的 NULL許容
PRIMARY KEY 一意識別 不可
FOREIGN KEY 参照整合性 可(設定による)
UNIQUE 値の重複禁止 可(DBMSによる)
NOT NULL NULL禁止 不可
CHECK 値の範囲制限
DEFAULT デフォルト値設定

3. 参照整合性

参照整合性(Referential Integrity)は、外部キーが参照する値が、参照先テーブルに存在することを保証する制約である。

Table 6. 参照整合性違反の例

操作 違反例 結果
INSERT 存在しない部署IDで社員を登録 エラー(拒否)
UPDATE 社員の部署IDを存在しない値に変更 エラー(拒否)
DELETE 社員が所属する部署を削除 エラーまたは連鎖削除
-- 参照整合性の例
-- 1. 部署テーブル(親)
CREATE TABLE departments (
    department_id INTEGER PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);

-- 2. 社員テーブル(子)
CREATE TABLE employees (
    employee_id INTEGER PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    department_id INTEGER,
    FOREIGN KEY (department_id) REFERENCES departments(department_id)
);

-- 正常なINSERT
INSERT INTO departments VALUES (1, '営業部');
INSERT INTO employees VALUES (101, '田中太郎', 1);  -- OK

-- 参照整合性違反(エラー)
INSERT INTO employees VALUES (102, '鈴木花子', 99);  -- 部署ID 99は存在しない
-- ERROR: Foreign key constraint violated
循環参照に注意
テーブルA → テーブルB → テーブルA のような循環参照は避けるべきである。データの挿入順序に依存関係が生じ、メンテナンスが困難になる。

4. まとめ

Table 7. 第3章のまとめ

概念 内容
主キー タプルを一意に識別、非NULL、重複不可
外部キー 他テーブルの主キーを参照、リレーション間の関連付け
候補キー 主キーになりうる最小の属性集合
代理キー 人工的に生成したキー(AUTO_INCREMENT等)
一意制約 値の重複を禁止(NULLは許容可能)
NOT NULL制約 NULL値を禁止
CHECK制約 値の範囲・条件を制限
参照整合性 外部キーが参照先に存在することを保証
参照アクション CASCADE, SET NULL, RESTRICT等
参考・免責事項
本コンテンツは2025年12月時点の情報に基づいて作成されています。制約の動作はDBMS製品により異なる場合があります。詳細は各製品のドキュメントをご確認ください。