正規化
データの整合性を保ち、冗長性や矛盾を防ぐためにテーブルを適切に分割・再構成する操作のこと。
用語
関数従属性(Functional Dependency, FD)
- ある列(または列の組)が決まれば、他の列の値も一意に決まる関係。
- 記法:A → B(Aが決まればBが一意に決まる)
- 例)社員IDがわかれば、社員名がわかる「社員ID → 社員名」
無損失分解(Lossless Decomposition)
- テーブルを複数に分解しても、情報を失わずに正確に元に戻せるようにする性質。
- 正規化後の複数テーブルは、主キー/外部キーによって結合可能で、元の情報を無損失で再構成できる。
- 前提: 正規化の過程では必ず無損失分解が行われるべき。
- 例)
- テーブル:#学生ID, 名前, 科目, 教員
- 正規化後:
- #学生ID, 名前
- #学生ID, 科目, 教員
部分関数従属(Partial Dependency)
-
複合主キーの一部の属性にのみ依存している関数従属のこと。
-
つまり、ある列が主キーの一部に対して関数従属があることです。
-
「多対1関係」か「多対多関係」かによって、正規化後のテーブルが異なる。
分類 説明 例 正規化の影響 多対1(many-to-one) 一方(従属側)が他方(主側)にだけ依存している 社員 → 会社
社員ID, 会社ID, 会社名部分関数従属が発生しやすく、2NFで会社名を分離する 多対多(many-to-many) 両方が複数の関連を持つため、中間テーブルが必要 学生 ↔ 科目
学生ID, 科目ID, 学生名, 科目名中間テーブルの設計で部分従属が入り込みやすく、注意が必要 -
排除対象:第2正規形(2NF)
-
例1)社員IDは会社内でユニークと仮定する
- テーブル:#会社ID, 会社名, #社員ID, 社員名
- #会社IDがわかれば、会社名がわかる「#会社ID → 会社名」
- #会社IDと#社員IDがわかれば、社員名がわかる「#会社ID, #社員ID → 社員名」
- 正規化後:
- #会社ID, 会社名
- #会社ID, #社員ID, 社員名
- テーブル:#会社ID, 会社名, #社員ID, 社員名
-
例2)中間テーブルの利用
- テーブル:#学生ID, 学生名, #科目ID, 科目名
- 学生IDがわかれば、学生名がわかる「#学生ID → 学生名」
- 科目IDがわかれば、科目名がわかる「#科目ID → 科目名」
- 正規化後:
- #学生ID, 学生名
- #科目ID, 科目名
- #学生ID, 科目ID
- テーブル:#学生ID, 学生名, #科目ID, 科目名
推移的関数従属(Transitive Dependency)
- A → B → C のように、主キーを介さずに間接的に依存している関係。
- 排除対象:第3正規形(3NF)
- 例)
- テーブル:#社員ID, 部署名, 部署場所
- #社員ID がわかれば、部署名 がわかる
- 部署名 がわかれば、部署場所 がわかる
- つまり、間接的に#社員ID がわかれば、 部署場所 がわかる
- 正規化後:
- #社員ID, 部署名
- #部署名, 部署場所
- テーブル:#社員ID, 部署名, 部署場所
多値従属性(Multivalued Dependency, MVD)(≒ 多値依存)
- 主キーに対して、複数の独立した値のセットが存在する関係。
- 排除対象:第4正規形(4NF)
- 記法:A ⇉ B
- 例)著者が複数の電話番号と複数のメールアドレスを持つ
- テーブル:#著者ID, 著者名, 電話番号, メールアドレス
- 1人の著者が複数の電話番号と複数のメールアドレスを持つ。
- 正規化後:
- #著者ID, 著者名
- #著者ID, #電話番号
- #著者ID, #メールアドレス
- テーブル:#著者ID, 著者名, 電話番号, メールアドレス
結合従属性(Join Dependency, JD)(≒ 結合依存)
- リレーションが複数のサブリレーションに分割されても、自然結合で元に戻せる必要があるという制約。
- すべての結合従属性が候補キーに基づくとは限らない。
- 排除対象:第5正規形(5NF)
- 例)
- テーブル:#社員ID, #部署ID, #勤務地
- #社員ID, #部署ID
- #部署ID, #勤務地
- #社員ID, #勤務地
- テーブル:#社員ID, #部署ID, #勤務地
- 5NFは、すべての結合従属性を満たすことが必要。
目的
- データの重複を排除する
- 更新時の不整合を防ぐ
- 論理的な構造を持たせて保守しやすくする
操作内容
- テーブルの分割(分離)
- 正規化には段階があり、一般に以下のような形で進められる:
正規形名 | 略称 | 内容・目的 |
---|---|---|
第1正規形 | 1NF | ・繰り返し(複数値)を排除 ・すべての列が単一の値(原子値)で構成される |
第2正規形 | 2NF | ・部分関数従属の排除(複合キーの一部にのみ依存する列を分離) |
第3正規形 | 3NF | ・推移的関数従属の排除(主キー以外の列を介した依存関係を解消) |
第3.5正規形(ボイス・コッド正規形) | BCNF | ・主キー以外の決定子(関数従属の原因)も候補キーであることが必要 |
第4正規形 | 4NF | ・多値依存の排除(1つのキーに対して複数の独立した値がある場合を分離) |
第5正規形 | 5NF | ・結合依存(Join Dependency)の排除(分割されたデータの再構成の正確性) |
- 実務では第3正規形まで正規化すれば十分なことが多い。
- BCNF 以降は、より複雑なデータ依存性に対処するための高度な正規化。
- 過度な正規化は性能低下や設計の複雑化を招く場合があるため、実用性とのバランスも重要。
第1正規形
- 一つのカラムに一つの値のみを持っている状態のこと。
- つまり、1つのセルには複数の値を持っていないということ(DBにおいてはセルとは言わないが)。
第2正規形
第3正規形
第3.5正規形
第4正規形
第5正規形
出典
-
Microsoft Learn「データベースの正規化の基礎」 第3正規形までを解説している
-
Qiita「本当にあったやらかしDB設計シリーズ一覧」 設計についてのアンチパターン的なもの
- https://qiita.com/abcaaa/items/e63e5f7d6f628da11362 (アクセス日:2025年5月14日)
-
BBH「【DB】第一正規形~第五正規形までを図解」 第5正規形までを解説している
- https://bbh.bz/2019/12/04/db-normalization-illustration/ (アクセス日:2025年5月14日)
-
Qiita「今更聞けないデータベースの正規化と正規形の種類についてまとめ」
- https://qiita.com/matsushou/items/6083335c4af29d69c642 (アクセス日:2025年5月14日)
-
Qiita「DBを正規化するということ」 第3正規形までを解説している + 正規化と非正規化のトレードオフに関して言及している
- https://qiita.com/yukihirasawa1206/items/c2dedcc51c01c1bd8ccc (アクセス日:2025年5月14日)