コンピューターサイエンス:アルゴリズム / OS / ネットワーク / DB

主キー・外部キー・候補キー

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

主キー・外部キー・候補キー

このレッスンで分かること

  • スーパーキー・候補キー・主キー・代替キーの違い
  • 自然キーと代理キー、どちらを選ぶか
  • 外部キーが提供する整合性とその限界

主キー・外部キー・候補キー とは

識別子としてのキーの種類と役割を整理する。本レッスンでは、主キー・外部キー・候補キー の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

キーの 4 階層

リレーショナル理論には 4 種類のキーがあります。混乱しがちなので順に整理します。

diagram (will load when visible)
  • スーパーキー (Super Key) — 行を一意に識別できるカラムの組み合わせなら何でも。(id, email, name) のようにムダな列が混じっていても可。
  • 候補キー (Candidate Key) — スーパーキーから冗長を取り除いて、最小の組み合わせにしたもの。(id)(email) などが該当。
  • 主キー (Primary Key) — 候補キーの中から代表として 1 つ選んだもの。テーブルに 1 つだけ。
  • 代替キー (Alternate Key) — 主キー以外の候補キー。UNIQUE 制約で表現する。

主キーの 3 条件

主キーは次の 3 つを必ず満たす必要があります。

  1. 一意性 — 重複しない
  2. NOT NULLNULL を許容しない
  3. 不変 — 一度割り当てたら原則変更しない

「不変」が地味に重要です。email をキーにすると、ユーザーがメールアドレスを変えるたびに外部キーまで更新が必要になります。

自然キー vs 代理キー

自然キー はビジネス上意味のある値です。社員番号、商品コード、ISBN、メールアドレスなど。 代理キー (Surrogate Key) はシステムが自動採番する意味のない値です。AUTO_INCREMENTINTUUID が代表。

実務ではほぼ常に 代理キー が推奨されます。理由は次の通りです。

  • ビジネスルール変更(マイナンバーの桁数変更など)に強い
  • インデックスサイズが小さくて高速
  • 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_INCREMENTUUID
サイズ4〜8 byte(INT ── 4 byte / BIGINT ── 8 byte)16 byte
連番性あり(推測されうる)なし
分散環境複数ノードで独立採番すると重複しうる(調整が必要)実質衝突しない(確率的に無視できる水準)
インデックス効率高いやや低い(順序がないので断片化)

分散 DB や API で外部公開する ID には UUID(特に UUIDv7 のような時刻順序付き)が、単一 DB の内部には AUTO_INCREMENT が向きます。

主キーは「一度決めると後で変更困難」。最初の設計で慎重に選ぶこと。

やってみよう

  • users テーブルで email を主キーにした場合と id を主キーにした場合、変更のしやすさを比較する
  • ON DELETE CASCADERESTRICT の挙動を実際に試す
  • 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 つができることを確認しましょう。

  1. 主キー・外部キー・候補キー の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. 主キー・外部キー・候補キー とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン