データ正規化
データベースの冗長性を排除し、データの一貫性を保つためにテーブル構造を分割・整理する手法
データベース設計
データ正規化とは
データ正規化 (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 で分析クエリを実行するならスタースキーマによる非正規化が適する。
現場での応用を知るには関連書籍も役立つ。