正規化 — 「1つの事実は1か所」に整える

1つの大きな表に何でも詰め込むと、同じデータが何度もコピーされる。すると「1か所だけ直して他が古いまま」の矛盾(更新異常)が起きます。正規化は、表を第1→第2→第3正規形へと分割し、重複を消して、それぞれの事実がただ1か所に存在するよう整える作業です。

1. 冗長なテーブル — 同じ事実の繰り返し

下は「誰が・どの科目を・成績いくつで受講したか」を1つの表に詰め込んだものです。学生名や科目名・担当教員が、行が増えるたびにそっくりコピーされているのが分かります。これが冗長性(redundancy)。ムダなだけでなく、次で見る「矛盾」の温床になります。

重複しているセルが光る
水色=同じ学生の情報が繰り返されている箇所、黄色=同じ科目の情報が繰り返されている箇所。田中さんの名前も、データベースの担当教員も、行の数だけ重複コピーされています。
POINT — 正規化のたった一つの目的 「1つの事実は、ただ1か所にだけ書く」。学生名は学生の表に1回、科目名は科目の表に1回。こうしておけば、コピーが食い違うことはそもそも起こり得なくなる。正規化とは、この状態へ表を作り替えることです。

2. 更新異常 — 1か所だけ直すと矛盾する

「データベース」の担当教員が山田先生から高橋先生に交代しました。表を更新しようとして、うっかり1行だけ書き換えると…… 同じ科目なのに担当教員が「高橋」と「山田」で食い違います。これが更新異常(update anomaly)。同じ事実がコピーで散らばっているからこそ起きる事故です。

1行だけ更新して矛盾を起こしてみる
「更新」を押すと1行目だけ高橋に変わり、同じデータベースの3行目は山田のまま。赤く点滅する食い違いが更新異常です。本来なら全コピーを漏れなく直さねばならず、1つでも忘れると矛盾します。
注意 — 異常は3種類ある 冗長な表では、更新異常(一部だけ直して食い違う)のほかに、挿入異常(受講者がいない新科目を登録できない=科目名の置き場がない)と、削除異常(最後の受講行を消すと科目の情報まで消える)も起きる。どれも「事実が独立して存在できていない」ことが原因。

3. 正規化 — 表を分けて重複を消す

解決策は、依存関係にしたがって表を分割することです。第2正規形では「主キーの一部だけで決まる列」(学生名・科目名など)を別の表へ切り出します。第3正規形では「間接的に決まる列」(教員→研究室のような連鎖)をさらに切り出します。ボタンで段階を切り替え、列が別表へ持ち上がっていく様子を見てください。

第1 → 第2 → 第3正規形へ分解する
黄色枠=主キー(&外部キー)。段階を進めるほど表が小さく分かれ、重複が消えていきます。分けてもキーでつなげば元通りに結合できるので、情報は失われません(JOIN は第3章参照)。
科目ID → 科目名, 教員   /   教員 → 研究室 「A → B」は関数従属:Aが決まればBが1つに定まる。科目IDが決まれば科目名と教員が定まり、教員が決まれば研究室が定まる。この矢印の連鎖(推移的従属)を断ち切るのが第3正規化。

4. 正規化後 — 事実は1か所、矛盾は起きない

正規化すると、担当教員は「科目テーブル」にただ1回だけ書かれ、受講テーブルは科目IDで参照するだけになります。だから教員が交代しても、直すのはたった1セル。参照している全行に自動で反映され、もう食い違いようがありません。第2節の異常と見比べてください。

1セル直すだけで全参照に反映される
科目テーブルの教員セルは1つだけ。更新するとそのセルが緑に光り、科目IDで参照している受講行すべてが(矢印の通り)同じ値を見ます。コピーが無いから矛盾も無い——これが正規化のご利益です。
一歩先へ — 正規化の先と、あえて崩す設計 第3正規形の先にはボイス・コッド正規形(BCNF)・第4・第5正規形があり、より微妙な冗長性を除く。一方で実務では、JOIN の回数を減らして読み取りを速くするため、あえて重複を残す「非正規化(denormalization)」も行う。正規化は目的ではなく道具。「矛盾を防ぐ安全性」と「速さ・単純さ」を天秤にかけて選ぶのが設計です。

5. まとめ