データモデル設計ガイド

正規化とは — 1NF〜5NF / BCNF の概要

正規化が何を解決するのか、各正規形が排除する問題を一覧で俯瞰する導入ページ。

正規化とは

正規化(normalization)は、1 つのテーブルに混ざった情報を、意味のまとまりごとに複数のテーブルに分割していくデータモデル設計の手順です。「同じ事実を 1 か所にだけ書く」状態を目指し、分割のルールを段階的に厳しくしたものが 1NF・2NF・3NF… と呼ばれる各「正規形」です。

たとえば次のような「注文」「顧客」「商品」が 1 テーブルに同居した orders から出発します。

order_idcustomercustomer_telproduct_nameprice
1001田中090-...SQL 入門2,800
1002田中090-...Git 入門2,500
1003鈴木080-...SQL 入門2,800

このテーブルでは「田中さんの電話番号」が顧客ごとに複数回、「SQL 入門の価格」が商品ごとに複数回書かれています。正規化はこれを customers / products / orders の 3 テーブルに分解し、各事実をただ 1 行に集約します。

  • customers (customer_id, name, tel) — 顧客の情報は 1 人 1 行
  • products (product_id, name, price) — 商品の情報は 1 点 1 行
  • orders (order_id, customer_id, product_id) — 注文は「誰が・何を」の組み合わせだけ

つまり正規化とは、「重複している情報を見つけて、別テーブルに切り出す」作業です。切り出し方のルールを定めたものが 1NF〜5NF/BCNF で、下位から順に満たしていく積み上げ構造になっています。

なぜ正規化するのか

重複があると、片方だけ更新されて矛盾が起きることがあります。これを 更新異常(update anomaly)と呼びます。先ほどの orders テーブルで「田中さんの電話番号」を変えたいとき、order_id=1001 だけ更新して 1002 を忘れると、同じ顧客なのに電話番号が 2 つ存在する状態になります。

正規化で「事実は 1 か所にだけ書く」形にしておけば、顧客の電話番号は customers テーブルの 1 行を更新するだけで済み、こうした不整合が構造的に起きなくなります。

逆に言えば、正規化は書き込みの一貫性を保証しますが、読み取りには複数テーブルの結合が必要になり、コストが上がる可能性があります。後述の「正規化しすぎ問題」につながります。

正規化前と正規化後を ER 図で比べる

正規化前と正規化後を ER 図で比べる diagram

上の説明を ER 図で並べると、正規化が「重複のあるテーブルを、意味ごとのテーブルに切り出す」作業であることがひと目でわかります。左の Beforeorders に顧客情報・商品情報が同居している状態、右の After はそれらを customers / products に切り出し、orders は FK だけを持つ形に整理した状態です。

Before のテーブルでは「田中さんの電話番号」「SQL 入門の価格」のような同じ事実が行数ぶん重複して保持されるため、更新漏れ=更新異常のリスクが構造的に残ります。After ではどの事実もただ 1 行にしか存在しないため、更新は 1 か所で済みます。

ER 図そのものの読み方(カラスの足記法の意味など)が不安な場合は ER 図の書き方・読み方 を先に確認してください。

正規形の一覧

正規化は段階的に進みます。下位の正規形を満たした上で、次の段階の条件を追加で満たす、という積み上げ構造です。実務では 3NF まで達していれば十分なことが多く、BCNF 以降は「候補キーが複雑なとき」や「多対多の組み合わせ表を作るとき」に検討します。

正規形排除する問題典型例詳細
1NF繰り返しグループ / 多値セルtags = "sql,db,index" のような CSV 列第 1 正規形(1NF)
2NF部分関数従属(複合キーの一部への従属)注文明細に product_name が紛れ込む第 2 正規形(2NF)
3NF推移関数従属(非キー → 非キー)employees (id, dept_id, dept_name)第 3 正規形(3NF)
BCNF候補キーが複数あるときの取りこぼし非キー側がキー構成列を決めてしまうケースボイス・コッド正規形(BCNF)
4NF独立した多値従属の同居スキルと言語を 1 テーブルに混在第 4 正規形(4NF)
5NF3 項以上の結合従属業者・部品・プロジェクトの 3 項関係第 5 正規形(5NF)

正規化しすぎは禁物 — 性能とのトレードオフ

3NF・BCNF まで完璧に正規化すると、シンプルな画面表示にも 5〜10 個のテーブル結合が必要になり、レイテンシ・CPU・読み取り負荷が跳ね上がることがあります。正規化は目的ではなく手段。書き込み一貫性 vs 読み取り性能のバランスで判断します。

非正規化を検討する典型ケース:

  • 読み取りが圧倒的に多く、書き込みは稀(マスタデータ、レポート用テーブル)
  • 集計済みの値をキャッシュしたい(記事のいいね数を articles.like_count に保持し、トリガや定期ジョブで更新)
  • 結合のコストが許容できない大規模テーブル間の関係

非正規化の代償は更新時の整合性管理。アプリ側 / トリガ / 定期再計算のいずれで保証するかをセットで設計します。

実務での目安

まず 3NF まで正規化してから、計測した上でホットなクエリだけ非正規化する — これが最も事故が少ない順序です。最初から非正規化すると、後から「どこに同じ事実が重複しているか」を追えなくなります。