ITの教科書検索
入門読了 約9分

主キーと外部キーとは ― 候補キー・複合キーの違い

主キーは表の行を1つに決める列、外部キーはほかの表の主キーを指す列です。候補キー・複合キー・代替キーの違いと、外部キーで拒否される操作を、操作を選んで確かめられます。

目次
  1. 主キーと外部キーとは
  2. キーの種類の一覧
  3. 候補キーから主キーを選ぶ
  4. 複合キーとは
  5. 外部キーが指す列
  6. 外部キーで拒否される操作
  7. 操作を選んで確かめる
  8. 代理キーと自然キー
  9. 練習問題

主キーは行を1つに決める列、外部キーはほかの表の主キーを指す列

主キーとは、表の中で行を1つに決めるための列です。同じ値の行を2つ置けず、値が無いことを表すNULLも入れられません。

外部キーとは、ほかの表の主キーと同じ値を入れて、その表の行を指す列です。外部キーを決めておくと、指す先の無い値を入れる操作をDBMSが拒否します。表を設計するときも、SQLで制約を書くときも、外部キー違反のエラーの原因を探すときも、この2つの考え方が必要です。

例には、RDBの記事の顧客と注文の表を少し変えて使います。顧客の表には、候補キーの例にするメールアドレスの列を足しました。注文の表は、商品の列を注文日に替え、顧客103の注文を除いた3行にしました。

顧客の表。顧客IDが主キー
顧客IDメールアドレス氏名
101misaki@example.com田中 美咲
102kenta@example.com佐藤 健太
103daisuke@example.com鈴木 大輔
注文の表。顧客IDが外部キー
注文ID顧客ID注文日
50011012026-10-01
50021022026-10-03
50031012026-10-05

キーの種類は、行が1つに決まるかと、余分な列があるかで分かれる

表のキーは、どの列の組なら行を1つに決められるかによって呼び名が変わります。次の表に、顧客の表と、後で使う注文明細の表を例にして、キーの種類を並べました。

キーの種類と、この記事の表での例
キーの種類意味この記事の例
スーパーキー値を見れば行が1つに決まる列の組。余分な列を含んでもよい顧客ID+氏名
候補キー行が1つに決まり、どの列を外しても決まらなくなる組顧客ID、メールアドレス
主キー候補キーから1つ選んだもの。重複とNULLを許さない顧客ID
代替キー主キーに選ばれなかった候補キーメールアドレス
複合キー2つ以上の列でできたキー注文明細の注文ID+商品ID
外部キーほかの表の主キーか候補キーと同じ値を持ち、その行を指す列注文の顧客ID

上の4つは、1つの表の中で行を決める列の組を、絞り込んだ順に並べています。複合キーは列の数に着目した呼び方で、候補キーや主キーが複合キーのこともあります。外部キーだけは、ほかの表とのつながりを表すキーです。

候補キーの中から1つを選んで主キーにする

顧客の表では、顧客IDの値を見れば行が1つに決まります。メールアドレスも、同じ値を2人が使わない決まりなら、行を1つに決められます。氏名は同姓同名の人がいるので、行を決められません。

顧客IDやメールアドレスのように、主キーになれる列の組を候補キーと呼びます。候補キーは、行を1つに決められ、しかも余分な列を含みません。顧客IDと氏名の組も行は決まりますが、氏名を外しても決まるので、候補キーではありません。

余分な列を含んでもよい組は、スーパーキーと呼びます。スーパーキーのうち、余分な列がないものが候補キーです。

スーパーキー行が1つに決まる列の組候補キー余分な列がない組顧客ID主キーに選ぶメールアドレス代替キー顧客ID+氏名メールアドレス+氏名キーにならない氏名重複しうるスーパーキー行が1つに決まる列の組候補キー余分な列がない組顧客ID主キーに選ぶメールアドレス代替キー顧客ID+氏名メールアドレス+氏名キーにならない氏名重複しうる
余分な列がない組が候補キーです。顧客ID+氏名も行は決まりますが、氏名は不要なので候補キーではありません。

候補キーが2つ以上あるときは、そのうち1つを選んで主キーにします。関係モデルを提案したCoddの1970年の論文も、余分な列のないキーが複数ある表では、1つを選んで主キーと呼ぶと書いています。選ばれなかった候補キーを、代替キーと呼びます。

主キーは1つだけで、代替キーにはUNIQUEとNOT NULLを付ける

SQLでは、主キーは1つの表に1つだけ置けます。PostgreSQLで2つの列にPRIMARY KEYを付けると、表を作る文がエラーになりました。そのため、代替キーにした列には、UNIQUEとNOT NULLを付けて重複とNULLを禁止します。

PostgreSQLの文書は、UNIQUEとNOT NULLを組み合わせた制約について、働きの上では主キーとほとんど同じだと説明しています。実際に、メールアドレスの列にこの2つを付けて、同じメールアドレスの顧客を追加すると、その文は拒否されました。制約の書き方は、CREATE TABLEと制約の記事にまとめました。

複合キーは、2つ以上の列の組で行を1つに決める

1回の注文で複数の商品を買うと、注文の中身は注文明細の表に1商品1行で入ります。この表では、注文IDにも商品IDにも同じ値が何度も現れます。2つを組にすると、行ごとに別の値になります。

主キー(複合キー)注文ID商品ID数量5001P0115001P0225003P011重複あり重複あり組にすると3行とも別
注文IDだけでも商品IDだけでも、同じ値の行があります。2つの列を組にすると3行とも別の値になるので、この組を主キーにします。

このように2つ以上の列でできたキーを、複合キーと呼びます。SQLでは、PRIMARY KEY (注文ID, 商品ID) のように、列を並べて表制約として書きます。注文IDと商品IDが同じ行をもう1行入れようとすると、主キーの重複として拒否されます。

注文明細の注文IDは、注文の表の主キーを指す外部キーでもあります。複合キーの一部の列が、同時に外部キーになることもあります。Coddの1970年の論文の例でも、3つの列の組が主キーで、それぞれの列が外部キーでした。

複合キーの一部の列だけで決まる列があると、表の中に同じ値がくり返し入ります。その表の分け方は、正規化の記事で部分関数従属として説明しています。

外部キーは、親の表の主キーか候補キーを指す

外部キーを持つ側の表を子の表、指される側の表を親の表と呼びます。例では注文の表が子、顧客の表が親です。MySQLの文書も、この呼び方で外部キーを説明しています。親と子が同じ表のこともあります。社員の表で、上司の列が同じ表の社員番号を指す場合がその例です。

外部キーが指す先は、ふつうは親の表の主キーです。PostgreSQLでは、UNIQUEを付けた代替キーも指せます。同じ値が入りうる氏名の列を指そうとすると、外部キーを定義する文がエラーになりました。

主キーと違い、外部キーの値は複数の行で同じでかまいません。注文5001と5003は、どちらも顧客101を指しています。外部キーの列にNOT NULLを付けなければ、NULLも入れられます。

外部キーでつないだ2つの表は、結合して読めます。書き方はJOINの記事で説明しています。どの表に外部キーを置くかは、E-R図の記事で説明する1対多の関連から決まります。

外部キーがあると、親のない子の行と、子のある親の削除が拒否される

外部キーは、指す先の無い子の行を作らせません。この決まりを参照制約と呼びます。参照制約が働いていれば、表どうしのつながりは食い違いません。この状態を参照整合性と呼びます。

DBMSが確かめる相手は、どちらの表を操作するかで変わります。子の表に行を足すときや外部キーの値を変えるときは、親の表にその値があるかを確かめます。親の表の行を消すときや主キーの値を変えるときは、子の表からその行が指されていないかを確かめます。

顧客テーブル(親)顧客ID(主キー)メールアドレス氏名参照される側注文テーブル(子)顧客ID(外部キー)注文ID(主キー)注文日参照する側参照する注文の追加・変更で確認顧客の削除・変更で確認顧客テーブル(親)顧客ID(主キー)メールアドレス氏名注文テーブル(子)顧客ID(外部キー)注文ID(主キー)注文日参照する注文の追加・変更で確認顧客の削除・変更で確認
点線の矢印の先が、DBMSが確かめる表です。注文を足すときは顧客の表を、顧客を消すときは注文の表を確かめます。

子の表の行を消す操作では、何も確かめません。子の行が消えても、指す先の無い行は生まれないからです。親の表に行を足す操作でも、同じ理由で何も確かめません。

操作を選んで、受け付けられるか拒否されるかを確かめる

次の図では、最初に示した顧客と注文の表に、7つの操作を試せます。子の表への操作も、親の表への操作も選べます。図に出る結果は、PostgreSQLで同じ表に実行して確かめたものです。

顧客の表(親)

顧客IDメールアドレス
101misaki@example.com
102kenta@example.com
103daisuke@example.com

注文の表(子)

注文ID顧客ID注文日
50011012026-10-01
50021022026-10-03
50031012026-10-05

試す操作を選ぶ

INSERT INTO 注文 VALUES (5004, 101, '2026-10-07');

子の表への操作DBMSが確かめること:顧客の表に顧客ID 101 の行があるか。あります。

○受け付けられる

外部キーの値101は顧客の表にあるので、新しい注文の行は追加されます。

顧客101の削除と、顧客102の顧客IDの変更は、どちらも親の表への操作です。どちらの行も子の注文から指されているので、拒否されます。注文の無い顧客103なら削除できます。PostgreSQLもMySQLも、外部キーの動作を指定しないときは、子から指されている親の行の削除や主キーの変更をエラーにします。

親の行を消すと子の行も一緒に消える設定もあります。その書き方は、CREATE TABLEと制約の記事で触れています。

主キーには、番号を振る代理キーと、業務の値を使う自然キーがある

顧客IDのように、行を区別するためだけに振った番号を主キーにしたものを、代理キーまたはサロゲートキーと呼びます。メールアドレスのように、業務で使う値そのものを主キーにしたものは自然キーです。

自然キーは、値が後から変わることがあります。メールアドレスを主キーにすると、変えるたびに注文の表の外部キーも直さなければなりません。前の節で見たとおり、子から指されている主キーの値を変える文は、そのままでは拒否されます。

代理キーを主キーにすれば、メールアドレスを変えても顧客の表の1行が変わるだけです。PostgreSQLで試すと、注文から指されている顧客102のメールアドレスの変更は受け付けられました。メールアドレスの列はUNIQUEとNOT NULLを付けて代替キーにしておけば、同じ値の登録も防げます。

連番の値は、DBMSに振らせることもできます。PostgreSQLでは、GENERATED ALWAYS AS IDENTITY を付けた列が、行を追加するたびに値を作ります。番号の付け方そのものは、コード設計の記事で説明しています。

参考にした資料

練習問題(全5問)

Q1候補キーの説明として正しいものはどれ?
Q2社員の表で社員番号を主キーにした。メールアドレスも社員ごとに重ならず、必ず入っている。このメールアドレスの列を何と呼ぶ?
Q3注文明細の表(注文ID・商品ID・数量)では、1つの注文に複数の商品が入り、同じ商品も別の注文に出てくる。主キーとして適切なものはどれ?
Q4注文の表の顧客IDが、顧客の表の顧客IDを参照する外部キーになっている。ON DELETEなどの動作は指定していない。拒否される操作はどれ?
Q5外部キーの値について正しいものはどれ?

選んでから「採点する」を押すと、解説つきで答え合わせができます。

関連記事

おすすめの本 PR

セキュリティとデータベースは、基本情報技術者試験の対策本でまとめて学べます。

目的別の本の選び方を見る

データベースの記事を続けて読む

データベース 全36本中3本目