第4章 正規化

更新日:2025年12月28日

🎧

この章を音声で聴く

再生速度:
本章では、データベース設計における正規化理論について解説する。正規化は、データの冗長性を排除し、更新異常を防止するためのテーブル設計手法である。関数従属性の概念を理解し、第1正規形から第3正規形、さらにボイス・コッド正規形(BCNF)までの段階的な正規化プロセスを学ぶ。また、正規化の目的と限界についても考察する。

1. 正規化の目的

1.1 データ冗長性

データ冗長性(Data Redundancy)とは、同じデータが複数箇所に重複して格納されている状態を指す。冗長性は以下の問題を引き起こす。

Table 1. 冗長性のあるテーブル例(非正規形)

注文ID 顧客名 顧客住所 商品名 単価
1001 田中太郎 東京都新宿区 りんご 200
1002 田中太郎 東京都新宿区 みかん 150
1003 鈴木花子 大阪府大阪市 りんご 200

上記テーブルでは、「田中太郎」の住所が2回、「りんご」の単価が2回格納されている。これがデータ冗長性である。

1.2 更新異常

データ冗長性は、3種類の更新異常(Update Anomaly)を引き起こす。

Table 2. 更新異常の種類

異常の種類 説明
挿入異常 不要な情報がないと挿入できない 注文がない顧客を登録できない
更新異常 一部の更新漏れで不整合が発生 田中太郎の住所を1行だけ変更すると矛盾
削除異常 削除時に必要な情報も消える 注文1003を削除すると鈴木花子の情報が消失
正規化の目的
正規化の主な目的は、(1) データ冗長性の排除、(2) 更新異常の防止、(3) データ整合性の向上、(4) ストレージの効率化である。ただし、過度な正規化はJOIN操作の増加によるパフォーマンス低下を招く可能性がある。

2. 関数従属性

関数従属性(Functional Dependency)は、正規化理論の基礎となる概念である。属性Xの値が決まると属性Yの値が一意に決まる関係を「YはXに関数従属する」といい、X → Y と表記する。

Table 3. 関数従属性の例

関数従属性 意味 説明
社員ID → 氏名 社員IDが決まれば氏名が決まる 1人の社員に1つの氏名
社員ID → 部署ID 社員IDが決まれば部署IDが決まる 1人の社員は1つの部署に所属
部署ID → 部署名 部署IDが決まれば部署名が決まる 1つの部署に1つの名前
{注文ID, 商品ID} → 数量 注文IDと商品IDで数量が決まる 複合キーへの従属

完全関数従属と部分関数従属

完全関数従属:複合キー全体に従属(例:{注文ID, 商品ID} → 数量)

部分関数従属:複合キーの一部に従属(例:{注文ID, 商品ID} のうち注文ID → 顧客名)

推移的関数従属

X → Y かつ Y → Z のとき、X → Z を推移的関数従属という。例:社員ID → 部署ID → 部署名

3. 正規形

Fig. 1. 正規化のプロセス

正規化のプロセス
非正規形からBCNFまでの正規化プロセス。実務では第3正規形までが一般的。

3.1 第1正規形

第1正規形(1NF: First Normal Form)は、すべての属性が原子的(atomic)であることを要求する。つまり、繰り返し項目や複数の値を含むセルがあってはならない。

Table 4. 非正規形から第1正規形への変換

非正規形(1NFに違反)
注文ID 顧客名 商品リスト
1001 田中太郎 りんご, みかん, バナナ

↓ 第1正規形に変換

第1正規形(1NF)
注文ID 顧客名 商品
1001 田中太郎 りんご
1001 田中太郎 みかん
1001 田中太郎 バナナ

3.2 第2正規形

第2正規形(2NF: Second Normal Form)は、第1正規形であり、かつすべての非キー属性が主キーに完全関数従属することを要求する。部分関数従属を排除する。

Table 5. 第1正規形から第2正規形への変換

第1正規形(2NFに違反)- 部分関数従属あり
注文ID 商品ID 数量 顧客名 商品名
1001 P01 3 田中太郎 りんご

主キー: {注文ID, 商品ID}

部分関数従属: 注文ID → 顧客名(商品IDに依存しない)

部分関数従属: 商品ID → 商品名(注文IDに依存しない)

↓ 第2正規形に分解

-- 注文テーブル
CREATE TABLE orders (
    order_id INTEGER PRIMARY KEY,
    customer_name VARCHAR(100)
);

-- 商品テーブル
CREATE TABLE products (
    product_id INTEGER PRIMARY KEY,
    product_name VARCHAR(100)
);

-- 注文明細テーブル
CREATE TABLE order_details (
    order_id INTEGER,
    product_id INTEGER,
    quantity INTEGER,
    PRIMARY KEY (order_id, product_id)
);

3.3 第3正規形

第3正規形(3NF: Third Normal Form)は、第2正規形であり、かつすべての非キー属性が主キーに推移的関数従属しないことを要求する。

Table 6. 第2正規形から第3正規形への変換

第2正規形(3NFに違反)- 推移的関数従属あり
社員ID 氏名 部署ID 部署名
E001 田中太郎 D01 営業部
E002 鈴木花子 D01 営業部

推移的関数従属: 社員ID → 部署ID → 部署名

↓ 第3正規形に分解

-- 社員テーブル
CREATE TABLE employees (
    employee_id VARCHAR(10) PRIMARY KEY,
    name VARCHAR(100),
    department_id VARCHAR(10)
);

-- 部署テーブル
CREATE TABLE departments (
    department_id VARCHAR(10) PRIMARY KEY,
    department_name VARCHAR(100)
);

3.4 BCNF

ボイス・コッド正規形(BCNF: Boyce-Codd Normal Form)は、第3正規形のより厳密な形である。すべての関数従属において、決定項(左辺)がスーパーキーでなければならない。

Table 7. 第3正規形とBCNFの違い

正規形 条件
3NF 非キー属性が主キーに推移的従属しない
BCNF すべての関数従属の決定項がスーパーキー
実務での正規化レベル
実務では第3正規形まで正規化することが一般的である。BCNFは理論的には望ましいが、分解により情報の損失が発生する場合がある。また、第4正規形(4NF)、第5正規形(5NF)も存在するが、実務での適用は稀である。

4. 正規化の限界

正規化には利点が多いが、以下の点に注意が必要である。

Table 8. 正規化の利点と欠点

利点 欠点
データ冗長性の排除 JOIN操作の増加
更新異常の防止 クエリの複雑化
ストレージ効率の向上 パフォーマンス低下の可能性
データ整合性の向上 設計の複雑化

非正規化(Denormalization)

パフォーマンスを優先する場合、意図的にテーブルを非正規化することがある。特に、読み取りが多く更新が少ないシステムでは、JOINを減らすために冗長性を許容することがある。

正規化の実践指針

Step 1:まず第3正規形まで正規化する

Step 2:パフォーマンステストを実施

Step 3:ボトルネックがJOINにある場合のみ、部分的に非正規化を検討

Step 4:非正規化する場合は、整合性維持の仕組み(トリガー等)を検討

5. まとめ

Table 9. 正規形の一覧

正規形 要件 排除するもの
1NF すべての属性が原子的 繰り返し項目、複合値
2NF 1NF + 部分関数従属なし 複合キーの一部への従属
3NF 2NF + 推移的関数従属なし 非キー間の従属関係
BCNF すべての決定項がスーパーキー キー以外からの関数従属
参考・免責事項
本コンテンツは2025年12月時点の情報に基づいて作成されています。正規化理論はE.F.Coddにより1970年代に確立されました。実務での適用は要件とパフォーマンスを考慮して判断してください。