正規化は「引っ越しの断捨離」だ ─ 1NF・2NF・3NFを3分で完全理解
この記事の目的
「このテーブル、第三正規形になってないね」
会議でエンジニアがそう言った瞬間、あなたは何食わぬ顔でうなずいた。内心は「???」だったけど。
正規化。データベースの話になると必ず出てくる。1NF、2NF、3NF...。数字が増えるほどエラそうだけど、違いがわからない。
大丈夫。この記事を読み終えれば、3つの正規形を二度と混同しない。
TL;DR(30秒で分かるまとめ)
| 正規形 | やること | 語呂合わせ |
|---|---|---|
| 1NF | 1つのマスに1つの値 | 「1マス1個」 |
| 2NF | 主キーの「一部」に依存するものを追い出す | 「2度手間をなくす」 |
| 3NF | 主キー「以外」に依存するものを追い出す | 「3角関係を解消」 |
正規化を「引っ越しの断捨離」で理解する
あなたは引っ越しをすることになった。
荷物を整理しながら、3段階で部屋をキレイにしていく。これが正規化だ。
第一正規形(1NF):「1マス1個」
散らかった状態(正規化前)
引っ越し前のあなたの部屋。1つの引き出しに、いろんなものがごちゃ混ぜ。
【ダメな例:1つのセルに複数の値】
┌────────┬─────────────────────────┐
│ 社員名 │ 担当プロジェクト │
├────────┼─────────────────────────┤
│ 田中 │ A案件, B案件, C案件 │ ← 1マスに3つ入ってる!
│ 鈴木 │ B案件, D案件 │ ← 1マスに2つ入ってる!
└────────┴─────────────────────────┘
1NFで整理した状態
「1マス1個」のルールを適用。
【第一正規形(1NF)】
┌────────┬──────────────────┐
│ 社員名 │ 担当プロジェクト │
├────────┼──────────────────┤
│ 田中 │ A案件 │ ← 1マス1個!
│ 田中 │ B案件 │ ← 1マス1個!
│ 田中 │ C案件 │ ← 1マス1個!
│ 鈴木 │ B案件 │ ← 1マス1個!
│ 鈴木 │ D案件 │ ← 1マス1個!
└────────┴──────────────────┘
語呂合わせ:「1(イチ)マス1(イチ)個」
1NF → 1マス1個
1つのセルには1つの値だけ。カンマ区切りで複数入れちゃダメ。
第二正規形(2NF):「2度手間をなくす」
1NFだけど、まだ問題がある状態
1NFは達成した。でも、よく見ると同じ情報を何度も書いている。
【1NFだけど2NFじゃない例】
主キー = 社員ID + プロジェクトID(複合キー)
┌────────┬────────────┬────────────┬────────────┐
│ 社員ID │ プロジェクト │ 社員名 │ 担当時間 │
├────────┼────────────┼────────────┼────────────┤
│ 001 │ A案件 │ 田中太郎 │ 40時間 │
│ 001 │ B案件 │ 田中太郎 │ 20時間 │ ← 「田中太郎」また書いてる!
│ 001 │ C案件 │ 田中太郎 │ 30時間 │ ← 「田中太郎」また書いてる!
│ 002 │ B案件 │ 鈴木花子 │ 50時間 │
└────────┴────────────┴────────────┴────────────┘
↑
「社員名」は「社員ID」だけで決まる
(プロジェクトIDは関係ない)
「田中太郎」という名前が3回も出てくる。これ、田中さんが結婚して名字が変わったら、3箇所直さないといけない。2度手間どころか3度手間だ。
2NFで整理した状態
「主キーの一部だけで決まるもの」を別テーブルに追い出す。
【第二正規形(2NF)】
【社員テーブル】
┌────────┬────────────┐
│ 社員ID │ 社員名 │
├────────┼────────────┤
│ 001 │ 田中太郎 │ ← 1回だけ!
│ 002 │ 鈴木花子 │ ← 1回だけ!
└────────┴────────────┘
【担当テーブル】
┌────────┬────────────┬────────────┐
│ 社員ID │ プロジェクト │ 担当時間 │
├────────┼────────────┼────────────┤
│ 001 │ A案件 │ 40時間 │
│ 001 │ B案件 │ 20時間 │
│ 001 │ C案件 │ 30時間 │
│ 002 │ B案件 │ 50時間 │
└────────┴────────────┴────────────┘
語呂合わせ:「2度手間をなくす」
2NF → 2度手間をなくす
同じ情報を何度も書く無駄を排除。主キーの一部に依存するものは別テーブルへ。
第三正規形(3NF):「3角関係を解消」
2NFだけど、まだ問題がある状態
2NFは達成した。でも、まだ変な依存関係が残っている。
【2NFだけど3NFじゃない例】
主キー = 社員ID
┌────────┬──────────┬──────────┬──────────────┐
│ 社員ID │ 社員名 │ 部署ID │ 部署名 │
├────────┼──────────┼──────────┼──────────────┤
│ 001 │ 田中太郎 │ D01 │ 営業部 │
│ 002 │ 鈴木花子 │ D01 │ 営業部 │ ← 「営業部」また書いてる!
│ 003 │ 山田次郎 │ D02 │ 開発部 │
└────────┴──────────┴──────────┴──────────────┘
社員ID → 部署ID → 部署名
↑ ↑
主キー 主キーじゃないのに
部署名を決めてる!
「部署名」は「社員ID」が直接決めているんじゃない。「部署ID」が決めている。
これは3角関係だ。
社員ID ─────→ 部署ID
│ │
│ ↓
└─ ─ ─ ─→ 部署名
「社員ID → 部署ID → 部署名」という三角形の関係
3NFで整理した状態
「主キー以外に依存するもの」を別テーブルに追い出す。
【第三正規形(3NF)】
【社員テーブル】
┌────────┬──────────┬──────────┐
│ 社員ID │ 社員名 │ 部署ID │
├────────┼──────────┼──────────┤
│ 001 │ 田中太郎 │ D01 │
│ 002 │ 鈴木花子 │ D01 │
│ 003 │ 山田次郎 │ D02 │
└────────┴──────────┴──────────┘
【部署テーブル】
┌────────┬──────────────┐
│ 部署ID │ 部署名 │
├────────┼──────────────┤
│ D01 │ 営業部 │ ← 1回だけ!
│ D02 │ 開発部 │ ← 1回だけ!
└────────┴──────────────┘
語呂合わせ:「3角関係を解消」
3NF → 3角関係を解消
「A → B → C」という三角形の依存関係を断ち切る。主キー以外に依存するものは別テーブルへ。
図解:3つの正規形を一枚で
┌─────────────────────────────────────────────────────────────┐
│ 正規化の3ステップ │
└─────────────────────────────────────────────────────────────┘
【正規化前】ゴミ屋敷状態
┌─────────────────────────────────────────┐
│ 1つのマスに複数の値がゴチャゴチャ │
│ 同じ情報があちこちに重複 │
│ 変な依存関係がグチャグチャ │
└─────────────────────────────────────────┘
│
▼ 「1マス1個」
┌─────────────────────────────────────────┐
│ 【1NF】繰り返しの排除 │
│ │
│ 1つのセルには1つの値だけ │
└─────────────────────────────────────────┘
│
▼ 「2度手間をなくす」
┌─────────────────────────────────────────┐
│ 【2NF】部分関数従属の排除 │
│ │
│ 主キーの「一部」に依存するものを分離 │
└─────────────────────────────────────────┘
│
▼ 「3角関係を解消」
┌─────────────────────────────────────────┐
│ 【3NF】推移的関数従属の排除 │
│ │
│ 主キー「以外」に依存するものを分離 │
└─────────────────────────────────────────┘
ストーリーで覚える語呂合わせ
引っ越しの日。あなたは荷物を整理している。
**「1マス1個」**で、ごちゃ混ぜの引き出しを整理した。(1NF達成)
すると、同じ本が3冊出てきた。**「2度手間をなくす」**ために、2冊は捨てた。(2NF達成)
さらに片付けると、友達から借りたまま返してない本を発見。**「3角関係を解消」**するために、ちゃんと返すことにした。(3NF達成)
1マス1個 → 2度手間なくす → 3角関係解消
この順番で覚えれば、もう忘れない。
まとめ
| 正規形 | 何を排除? | どう覚える? |
|---|---|---|
| 1NF | 繰り返し(1セルに複数値) | 1マス1個 |
| 2NF | 主キーの一部への依存 | 2度手間をなくす |
| 3NF | 主キー以外への依存 | 3角関係を解消 |
最後に
正規化の目的は、**「同じ情報を何度も書かない」**こと。
なぜそれが大事か?
- データを更新するとき、1箇所直せば済む
- 矛盾したデータが生まれない
- ストレージの無駄遣いを防げる
次にエンジニアが「第三正規形」と言ったら、こう返してみよう。
「三角関係は解消しないとね」
...たぶんウケる。たぶん。
この記事が役に立ったら、フォローしていただけると励みになります。
Discussion