データ正規化

データベースの冗長性を排除し、データの一貫性を保つためにテーブル構造を分割・整理する手法

データベース設計

データ正規化とは

データ正規化 (Normalization) は、リレーショナルデータベースの冗長性を排除し、更新異常 (Update Anomaly) を防ぐためにテーブル構造を分割・整理する手法である。Edgar F. Codd が 1970 年代に提唱した。

正規化の段階

非正規形 (冗長なデータ)

| 注文ID | 顧客名  | 商品1    | 商品2    | 商品3  |
|--------|---------|---------|---------|--------|
| 1      | Alice   | りんご   | バナナ   | NULL   |
| 2      | Bob     | りんご   | みかん   | バナナ |

問題: 商品数が増えるとカラムを追加する必要がある。

第 1 正規形 (1NF): 繰り返しグループの排除

| 注文ID | 顧客名  | 商品     |
|--------|---------|---------|
| 1      | Alice   | りんご   |
| 1      | Alice   | バナナ   |
| 2      | Bob     | りんご   |

第 2 正規形 (2NF): 部分関数従属の排除

注文テーブル:          注文明細テーブル:
| 注文ID | 顧客名  |   | 注文ID | 商品     |
|--------|---------|   |--------|---------|
| 1      | Alice   |   | 1      | りんご   |
| 2      | Bob     |   | 1      | バナナ   |
                       | 2      | りんご   |

第 3 正規形 (3NF): 推移的関数従属の排除

注文テーブル:          顧客テーブル:
| 注文ID | 顧客ID  |   | 顧客ID | 顧客名  | 住所    |
|--------|---------|   |--------|---------|---------|
| 1      | C001    |   | C001   | Alice   | 東京    |
| 2      | C002    |   | C002   | Bob     | 大阪    |

正規化 vs 非正規化

観点 正規化 非正規化
データの冗長性 なし あり
更新の一貫性 高い 低い (複数箇所を更新)
読み取り速度 遅い (JOIN が必要) 速い (1 回のクエリ)
書き込み速度 速い (1 箇所を更新) 遅い (複数箇所を更新)
用途 OLTP (RDS) OLAP (Redshift), NoSQL

DynamoDB と非正規化

DynamoDB は JOIN をサポートしないため、意図的に非正規化する。

// RDS (正規化): 注文 + 顧客を JOIN で取得
// DynamoDB (非正規化): 1 アイテムに埋め込む
{
  "orderId": "1",
  "customer": { "id": "C001", "name": "Alice" },
  "items": [
    { "product": "りんご", "price": 100 },
    { "product": "バナナ", "price": 200 }
  ]
}

DynamoDB では「アクセスパターンに合わせてデータを設計する」のが原則。正規化ではなく、クエリの効率を優先する。

判断基準

RDS でトランザクションの一貫性が重要なら正規化 (3NF) を採用する。DynamoDB で読み取り性能を優先するなら非正規化し、Redshift で分析クエリを実行するならスタースキーマによる非正規化が適する。

現場での応用を知るには関連書籍も役立つ。

関連用語