コンピューターサイエンス:アルゴリズム / OS / ネットワーク / DB
主キー・外部キー・候補キー
主キー・外部キー・候補キー
このレッスンで分かること
- スーパーキー・候補キー・主キー・代替キーの違い
- 自然キーと代理キー、どちらを選ぶか
- 外部キーが提供する整合性とその限界
主キー・外部キー・候補キー とは
識別子としてのキーの種類と役割を整理する。本レッスンでは、主キー・外部キー・候補キー の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
キーの 4 階層
リレーショナル理論には 4 種類のキーがあります。混乱しがちなので順に整理します。
- スーパーキー (Super Key) — 行を一意に識別できるカラムの組み合わせなら何でも。
(id, email, name)のようにムダな列が混じっていても可。 - 候補キー (Candidate Key) — スーパーキーから冗長を取り除いて、最小の組み合わせにしたもの。
(id)、(email)などが該当。 - 主キー (Primary Key) — 候補キーの中から代表として 1 つ選んだもの。テーブルに 1 つだけ。
- 代替キー (Alternate Key) — 主キー以外の候補キー。
UNIQUE制約で表現する。
主キーの 3 条件
主キーは次の 3 つを必ず満たす必要があります。
- 一意性 — 重複しない
- NOT NULL —
NULLを許容しない - 不変 — 一度割り当てたら原則変更しない
「不変」が地味に重要です。email をキーにすると、ユーザーがメールアドレスを変えるたびに外部キーまで更新が必要になります。
自然キー vs 代理キー
自然キー はビジネス上意味のある値です。社員番号、商品コード、ISBN、メールアドレスなど。
代理キー (Surrogate Key) はシステムが自動採番する意味のない値です。AUTO_INCREMENT の INT や UUID が代表。
実務ではほぼ常に 代理キー が推奨されます。理由は次の通りです。
- ビジネスルール変更(マイナンバーの桁数変更など)に強い
- インデックスサイズが小さくて高速
JOIN句がシンプル- ユーザー情報を露出しなくて済む
SQL クエリ
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY, -- 代理キー
email VARCHAR(255) UNIQUE NOT NULL -- 自然キー候補
);id が主キー、email が代替キー(候補キーだが選ばれなかった)です。
外部キー
外部キー (Foreign Key) は、別テーブルの主キーを参照することで関係を表現します。
SQL クエリ
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id)
);外部キーが提供するのは 参照整合性 です。存在しない user_id を入れようとするとエラーになり、孤児レコードが生まれません。
ON DELETE / ON UPDATE
親レコードが消えたときに子をどうするかを指定できます。
ON DELETE CASCADE— 親が消えたら子も自動削除ON DELETE SET NULL— 子の外部キーをNULLにON DELETE RESTRICT— 子が残っていたら親の削除を拒否。ON DELETE 句を省略した場合の既定はNO ACTIONで、多くの DB では RESTRICT と同じ挙動になる(厳密には制約チェックのタイミングが異なる場合がある)
SQL クエリ
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADEユーザー削除時に注文も全部消したいなら CASCADE ですが、業務システムでは「論理削除 + RESTRICT」が無難です。
複合主キー
order_items のように 2 列を組み合わせた主キーも合法です。
SQL クエリ
CREATE TABLE order_items (
order_id BIGINT,
product_id BIGINT,
PRIMARY KEY (order_id, product_id)
);ただし、複合主キーは JOIN や ORM の扱いが複雑になります。実務では代理キー id を立てて、(order_id, product_id) には UNIQUE 制約を貼る運用もよく見られます。
UUID か AUTO_INCREMENT か
代理キーには 2 系統あります。
| 観点 | AUTO_INCREMENT | UUID |
|---|---|---|
| サイズ | 4〜8 byte(INT ── 4 byte / BIGINT ── 8 byte) | 16 byte |
| 連番性 | あり(推測されうる) | なし |
| 分散環境 | 複数ノードで独立採番すると重複しうる(調整が必要) | 実質衝突しない(確率的に無視できる水準) |
| インデックス効率 | 高い | やや低い(順序がないので断片化) |
分散 DB や API で外部公開する ID には UUID(特に UUIDv7 のような時刻順序付き)が、単一 DB の内部には AUTO_INCREMENT が向きます。
主キーは「一度決めると後で変更困難」。最初の設計で慎重に選ぶこと。
やってみよう
usersテーブルでemailを主キーにした場合とidを主キーにした場合、変更のしやすさを比較するON DELETE CASCADEとRESTRICTの挙動を実際に試すUUIDを主キーにしたテーブルとBIGINT AUTO_INCREMENTのテーブルで、100 万件挿入時のサイズ差を計測する
よくある質問
Q. このトピックは実務でどう役立ちますか?
A. DB のクエリ最適化、API 設計、データ構造の選択など、設計判断の根拠になります。表面的にライブラリを使うだけでなく「なぜそれが速いのか」を理解できると、性能問題を未然に防げます。コーディング面接でも頻出のテーマです。
Q. 計算量はどう求めれば良いですか?
A. ループのネストごとに掛け算する、再帰なら漸化式から解く、というのが基本です。Big-O 表記は定数倍と低次の項を無視するため、n の指数(n²、n log n など)に注目してください。最悪・平均・最良の 3 つを意識すると説得力が増します。
Q. 覚えるべき定番アルゴリズムは何ですか?
A. 二分探索、クイックソート/マージソート、BFS/DFS、ダイクストラ、DP の基本問題(フィボナッチ・ナップサック)が必修です。これらを「白紙から書ける」状態にすると、応用問題が一気に解けるようになります。
次のレッスン
次は 正規化とは何か で、識別子としてのキーの種類と役割を整理する を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- 主キー・外部キー・候補キー の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. 主キー・外部キー・候補キー とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン