キーの階層 (スーパーキー・候補キー・主キー)
候補キーとは、テーブルの 1 行を一意に見分けられる列の組み合わせのうち「これ以上どれか 1 つでも削ったら見分けられなくなる」最小のものをいい、その中から実装上 1 つを選んで主キーとする。
「行を見分けるための鍵」にはいくつか種類がある
テーブルの中から特定の 1 行を指し示すには、他の行と区別できる目印が必要になる。 この目印になる列 (または列の組み合わせ) を キー と呼ぶ。
ややこしいのは、キーには 用途と性質による名前 がいくつかあること。 大きい枠から順に「スーパーキー ⊃ 候補キー ⊃ 主キー」の入れ子構造になっている。 以下の集合図と説明で全体像を掴んでおこう。
行を一意に識別できる属性集合すべて。関係のない属性を追加しても一意性は保たれるので、 極端に言えば「全属性」もスーパーキーになる。
スーパーキーのうち 極小 なもの (どれか 1 つでも列を削るとキーとして働かなくなる、ぎりぎりの最小構成)。 1 つのテーブルに候補キーが複数存在することもある。
候補キーのうち、実装上「これを行の識別に使う」と選んだ 1 つ。 外部キーが参照する対象になる。
候補キーのうち、主キーに選ばれなかったもの。 UNIQUE 制約を張るなどして一意性は保証される。
外側から順に「一意性を持つ属性集合」を絞り込んでいくと、スーパーキー ⊃ 候補キー ⊃ 主キー の階層になる。 代替キーは候補キーのうち主キーに選ばれなかったもの。
「極小」ってどういうこと?
候補キーの説明で「極小」という言葉が出てくる。これは「その中のどれか 1 つでも列を削ったら、もう行を一意に見分けられなくなる」ぎりぎりの状態を指す。
例えば (注文ID, 商品ID) という 2 列セットが候補キーだとする。 このセットから 注文ID だけを削って (商品ID) にすると、 同じ商品が複数の注文で買われていた場合に行が一意にならなくなる。 逆に 商品ID だけを削って (注文ID) にしても、同じ注文で複数商品を買っていれば一意にならない。 つまり (注文ID, 商品ID) は 「これ以上減らせない最小の組み合わせ」 になっている、というのが「極小」の意味。
ちなみに、この (注文ID, 商品ID) に 数量 を足した (注文ID, 商品ID, 数量) も 「行を一意に見分けられる列の組み合わせ」ではあるが、数量 は無くても一意に見分けられるので「極小」ではなく、 候補キーではなくスーパーキー止まりになる。
複数の列を組み合わせるキー (複合キー) と、他テーブルを参照するキー (外部キー)
キーは 1 つの列とは限らない。複合キー (composite key): 2 つ以上の列を組み合わせて初めて 1 行を見分けられる場合のキー。 よく出てくるのは「注文と商品を組み合わせて 1 つの明細行を表す」ような中間テーブルで、(注文ID, 商品ID) という 2 列セットが主キーになる。
外部キー (foreign key): 別テーブルの主キーを指し示すために持つ列。 たとえば「受注明細」テーブルに置いた 注文ID は「受注」テーブルの主キーを指し、商品ID は「商品」テーブルの主キーを指している。 テーブルを分割した時に生まれる「あっちのテーブルのこの行を指してる」という参照関係を保つのが役割。
実際にはこんな形になる。
| 注文IDPK | 注文日 |
|---|---|
| O001 | 2026-06-01 |
| O002 | 2026-06-02 |
| 商品IDPK | 商品名 |
|---|---|
| P01 | ノート |
| P02 | ペン |
| 注文IDPK | 商品IDPK | 数量 |
|---|---|---|
| O001 | P01 | 2 |
| O001 | P02 | 1 |
| O002 | P01 | 5 |
受注明細テーブルの (注文ID, 商品ID) は 複合キー (2 列セットで主キー)。 同時に、注文ID は 受注 テーブルへの外部キー・商品ID は 商品 テーブルへの外部キーになっている。
覚えておく用語: 非キー属性
次の 第2正規形・第3正規形から「非キー属性」という言葉が頻繁に出てくる。 字面通り「キーに含まれない列」のこと。
たとえば (社員ID, 氏名, 部署ID, 部署名) というテーブルで、 候補キーが 社員ID だけなら、氏名・部署ID・部署名の 3 つがすべて非キー属性。 「非キー属性が他の何にどう決まっているか」を見ることで、次の正規形に進める余地があるかを判断する。
主キーの選び方 (実務のコツ)
候補キーが複数あるときに、どれを主キーに選ぶかは実務でよく迷う。目安は以下の 4 つ。
- 値が変わらないもの: 主キーの値が途中で変わると、それを参照している外部キーも全部書き直すことになる。だから将来変わらない属性が望ましい。
- NULL にならないもの: NULL だと「値が無い」ので行を特定できない。主キーには NULL 不可の列を選ぶ。
- 短くて扱いやすいもの: 長い文字列や複数列のセットは、参照する他のテーブルからも扱いにくくなる。
- ちょうどいい業務キーが無ければ「代理キー」: 上記を満たす業務属性が無いなら、 連番 ID など「業務的な意味は無いけど、行を見分けるためだけの ID」を作って主キーにする。これを サロゲートキー (surrogate key) と呼ぶ。
よくある疑問
関連トピック
- 基礎なぜ正規化が必要か
正規化されていないテーブルでは、同じ事実を複数の行に重複して持つために、挿入・更新・削除の各操作で矛盾や情報損失が発生する。この「更新時異常」を体系的に排除するのが正規化の目的である。
- 基礎関数従属性
属性 X の値が決まると属性 Y の値も一意に決まる関係を関数従属という。この概念は 1NF〜3NF、BCNF まで正規化の全ステップの判定基準になる。部分関数従属・推移関数従属など派生概念も整理する。
- 基礎第1正規形
全ての属性がアトミック値をとり、繰り返しグループを含まない状態が第1正規形。非1NF (unnormalized form) の代表例を並置し、1NF に変換する具体的手続きを図解する。
もっと学びたい方へ(おすすめ書籍)
テーブル設計と正規化、パフォーマンス考慮のインデックス設計まで実務レベルで学べる定番書。第2版ではクラウド対応も強化。
IPAデータベーススペシャリスト試験の総合対策書。インデックス関連は本サイトと合わせて学ぶと理解が深まる。
SQLの本質的な使い方と、インデックスが効くクエリの書き方を学べる。ウィンドウ関数など現代SQLも網羅。
実務でやりがちなSQL・DB設計のアンチパターンとその回避策を体系的に学べる。
PostgreSQLの内部構造・ストレージ・インデックス機構を丁寧に解説。設計と運用計画の鉄則が学べる。
リレーショナルモデルの理論から、インデックス設計を含む実務で使えるSQLまで解説。
本セクションはAmazonアソシエイトのリンクを含みます。
もっと深くDBを学びたい方へ。
たいてっくが、SQL・データベース設計・パフォーマンスチューニング・ IPAデータベーススペシャリスト対策まで、1対1で学習をサポートします。まずは無料相談から。