コンピューターサイエンス:アルゴリズム / OS / ネットワーク / DB
正規化とは何か
正規化とは何か
このレッスンで分かること
- 正規化が解決する 3 つの更新異常
- 関数従属という概念の意味
- 1NF から 5NF までの全体像
正規化 とは
なぜ正規化が必要なのか、更新異常の概念を理解する。本レッスンでは、正規化 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
正規化が必要な理由
正規化 (Normalization) とは、テーブル設計を整理して データの冗長性 を排除し、更新異常 を防ぐ手続きです。1970 年代に E.F.Codd によって体系化されました。
「テーブルを分けるなんて、JOIN が増えて遅くなるだけでは」と思うかもしれません。しかし、正規化していない設計は 3 つの異常 を引き起こし、長期運用で必ず痛い目に遭います。
3 つの更新異常
例として、注文テーブルにユーザー情報を全部書いた「ダメな設計」を考えます。
| order_id | user_id | user_name | user_email | product | amount |
|---|---|---|---|---|---|
| 1 | 100 | Alice | alice@ex.com | Apple | 500 |
| 2 | 100 | Alice | alice@ex.com | Banana | 300 |
| 3 | 200 | Bob | bob@ex.com | Cherry | 800 |
ここで起きる 3 つの異常が次のものです。
1. 更新異常 (Update Anomaly) — Alice がメアドを変えたら 2 行更新が必要。1 行でも忘れると alice@ex.com と新メアドが混在し、データ不整合になる。
2. 挿入異常 (Insertion Anomaly) — まだ注文していない新規ユーザーを登録できない。product と amount が NULL の行を入れるしかない。
3. 削除異常 (Deletion Anomaly) — Bob の唯一の注文を取り消すと、Bob 自身の情報も消える。
正規化はこれらを 設計レベル で解決します。
実務では 3NF まで やれば十分とされ、4NF / 5NF はめったに使いません。
関数従属という考え方
正規化の中心概念が 関数従属 (Functional Dependency) です。「ある列の値が決まれば別の列の値が一意に決まる」関係を意味し、A -> B と書きます。
user_id -> user_name— ユーザー ID が決まれば名前は 1 つに決まる(order_id, product_id) -> quantity— 注文と商品の組が決まれば数量が決まるuser_id -> user_email— ユーザー ID が決まればメアドは 1 つに決まる
「user_id が決まれば user_name が決まる」のに、同じ user_id の行に異なる user_name が書ける状態が 冗長 であり、異常の原因です。
正規形のおおまかなイメージ
| 正規形 | 排除するもの | ひとことで言うと |
|---|---|---|
| 1NF | 繰り返し項目 | 各セルは原子値 |
| 2NF | 部分関数従属 | 複合キーの一部だけに依存しない |
| 3NF | 推移関数従属 | 非キー列同士で依存しない |
| BCNF | あらゆる関数従属 | 主キー候補のみが他を決める |
| 4NF | 多値従属 | 独立した多値属性を分ける |
| 5NF | 結合従属 | これ以上分解不能な最小単位 |
具体例で予習
先のテーブルを 3NF まで分解するとこうなります。
SQL クエリ
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100)
);
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE TABLE order_items (
order_id INT,
product VARCHAR(50),
amount INT,
PRIMARY KEY (order_id, product),
FOREIGN KEY (order_id) REFERENCES orders(id)
);ユーザー情報は users に 1 行ずつ。注文は orders で参照。商品明細は order_items に展開。これで Alice のメアド変更は 1 行で済み、Bob の注文を消しても Bob 自身は残ります。
トレードオフ
正規化のデメリットは JOIN が増えて読み取りが遅くなる ことです。レポートやダッシュボード用に、あえて 1 つのテーブルに集約することを 非正規化 と呼びます。実務では「OLTP は 3NF、OLAP は非正規化」のように使い分けます。
正規化は OLTP(オンライントランザクション)の世界。非正規化は OLAP(分析)の世界。
やってみよう
- 自分のプロジェクトの 1 番大きいテーブルを書き出し、関数従属を矢印で書いてみる
- 「同じ値が複数行に重複している列」を探す(それが冗長性のサイン)
- 3NF にしたときに何個のテーブルに分かれるか試算する
よくある質問
Q. なぜ正規化するのですか?
A. データの重複を排除し、更新時の不整合(更新異常・挿入異常・削除異常)を防ぐためです。第 3 正規形まで適用すると保守性が大きく上がります。一方で JOIN が増えるため、検索性能と保守性のバランスで非正規化することもあります。
Q. 1NF と 2NF の違いは?
A. 1NF は「各セルが単一値」、2NF は「主キーの一部だけに依存するカラムをテーブル分割」する形です。複合キーの片方だけに紐づく属性は別テーブルに切り出すと 2NF になります。1NF を満たさないと 2NF 以降の議論はできません。
Q. 全部正規化すれば最適ですか?
A. 理想ですが、JOIN が増えてパフォーマンスが落ちる場面では非正規化(カラム複製、計算結果のキャッシュ)も有効です。OLTP は 3NF、レポーティング用 DWH はスタースキーマ(非正規化)と、用途で使い分けるのが現代的なアプローチです。
次のレッスン
次は 第1正規形 で、なぜ正規化が必要なのか、更新異常の概念を理解する を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- 正規化とは何か の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. 正規化とは何か とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン