SQL初めてのSQL

Day 3書きかえる・設計する — INSERT/UPDATE/DELETEと表の設計

主キーと外部キー — 行を見分け、表と表をつなぐ

各行を一意に見分ける主キー(id)と、別の表を指す外部キーを理解し、JOINの土台を身につける。

たくさんの行の中から「その人」を確実に指すには

表には同じ名前の人が複数いるかもしれません。「田中さん」が3人いたら、名前だけでは「どの田中さんか」を確実に指せません。そこで、行ごとに重複しない番号を1つ持たせておきます。これが主キー(primary key)です。会員証の会員番号や、社員の社員番号と同じ考え方で、「1人ずつに割り振られた、絶対にかぶらない背番号」です。

  • 主キーは、その表の中で絶対に重複しない(同じ値が2つと無い)。
  • 多くの場合、id という名前の列がその役目を持つ。
  • 主キーが決まっていれば、WHERE id = 5 のように、たった1行を確実に指定できる。
SQL
-- users テーブル(イメージ)
-- id  | name  | age
-- 1   | 田中  | 20
-- 2   | 田中  | 34   ← 同じ名前でも id が違うので別人だと分かる
-- 3   | 佐藤  | 28

-- 「2番の田中さん」だけを確実に指せる
SELECT * FROM users WHERE id = 2;
名前がかぶっても、主キー id なら1人を確実に特定できる

なぜ番号で人を管理するのか

名前は変わることがあり(結婚や改名)、同姓同名もあります。名前を頼りに人を管理すると、取り違えが起きます。会員番号のように「変わらない・かぶらない番号」で管理すれば、名前が変わっても同じ人を追い続けられます。だからデータベースは id で行を見分けます。

別の表を指し示す「外部キー」

現実のデータは複数の表に分かれています。たとえば「利用者」の表と「注文」の表。注文の1件ずつには「誰が注文したか」を持たせたいですが、注文の表に名前や住所をまるごとコピーすると重複だらけになります。そこで注文の表には、利用者の id だけを書いておきます。この「別の表の主キーを指す列」を外部キー(foreign key)と呼びます。

SQL
-- orders テーブル(イメージ)
-- id | user_id | item
-- 1  | 2       | 本      ← user_id が 2 = users の id=2 の田中さんの注文
-- 2  | 3       | ペン     ← user_id が 3 = 佐藤さんの注文

-- user_id が外部キー。users テーブルの id を指している。
orders.user_id は users.id を指す外部キー

外部キーは、2日目までに見た JOIN の土台です。JOIN は「orders.user_id と users.id が一致する行どうしをつなぐ」ことで、注文と利用者の情報を1つの結果にまとめます。主キーと外部キーが「つなぎ目」の役割を果たしているのだと分かると、JOIN の意味がすっきり読めるようになります。

名前をコピーして持つ

注文ごとに氏名や住所をまるごと書くと、同じ情報が何度も重複し、住所変更のとき全部直す必要が出る。

idだけを指す(外部キー)

注文には user_id だけ持たせ、詳細は users を見に行く。情報は1か所にまとまり、直すのも1か所で済む。

AIにはこう聞く

「このテーブルの外部キーはどれですか? どの表のどの列を指していますか?」と聞くと、表どうしのつながり(つなぎ目)を教えてくれます。JOINの条件が読めないときも、まずこの関係をAIに整理してもらうと理解が早いです。

読んでも腑に落ちない所は、AIに噛み砕いてもらいましょう。

理解度チェック

答えられれば、面接で説明できる状態に一歩近づきます。

Q1

主キー(primary key)の説明として、最も正しいものはどれですか?

Q2

orders テーブルの user_id が users テーブルの id を指しているとき、user_id を何と呼びますか?

Q3

主キーと外部キーの関係を、会員番号のたとえを使って初心者に説明してください。

記述式です。まず自分の言葉で答えを考えてから、模範解答を開いて自己採点してください。