正規化って聞くとなんだか難しそうだけど、そんな難しいことはしていない。
DB を使いやすい状態にしているだけ。
正規化と正規形の違い
正規化・・・テーブルをさらに分割すること
正規形・・・正規化した結果できた形
第一正規形
- 各行が一意な状態
- 列に重複がない状態
次のような状態は、第一正規形ではない
// 列が重複している
受注テーブル
| 受注ID | 商品1 | 価格1 | 商品2 | 価格2 |
|--------|--------|--------|--------|--------|
| 1 | りんご | 100 | みかん | 80 |
| 2 | バナナ | 150 | | |
第一正規形に直すと次のような状態になる
| 受注ID | 明細番号 | 商品 | 価格 |
|--------|----------|--------|------|
| 1 | 1 | りんご | 100 |
| 1 | 2 | みかん | 80 |
| 2 | 1 | バナナ | 150 |
第二正規形
対象:複合キーのテーブル
- 第一正規形を満たしている状態
- 主キーの一部でさらに分けることができない状態
次のような状態は、第二正規形ではない
// 複合キーの一部である商品IDで商品名と価格が特定できる
受注明細テーブル(複合キー:受注ID + 商品ID)
| 受注ID* | 商品ID* | 商品名 | 価格 | 数量 |
|---------|---------|--------|------|------|
| 1 | A001 | りんご | 100 | 2 |
| 1 | A002 | みかん | 80 | 3 |
*がついている列が複合キー
第二正規形に直すと次のような状態になる
受注明細テーブル
| 受注ID* | 商品ID* | 数量 |
|--------|--------|------|
| 1 | A001 | 2 |
| 1 | A002 | 3 |
商品テーブル
| 商品ID | 商品名 | 価格 |
|--------|--------|------|
| A001 | りんご | 100 |
| A002 | みかん | 80 |
第三正規形
- 第二正規形を満たしている状態
- 主キー以外の項目でさらに分けることができない状態
次のような状態は、第三正規形ではない
// 顧客情報が注文ごとに重複している(山田、東京)
受注テーブル
| 受注ID* | 顧客名 | 顧客住所 | 商品ID |
|--------|--------|----------|---------|
| 1 | 山田 | 東京 | A001 |
| 2 | 山田 | 東京 | A002 |
*がついている列が主キー
第三正規形に直すと次のような状態になる
// 山田と東京が1回しか出てこなくなった
受注テーブル
| 受注ID* | 顧客ID | 商品ID |
|--------|--------|---------|
| 1 | C001 | A001 |
| 2 | C001 | A002 |
顧客テーブル
| 顧客ID* | 顧客名 | 顧客住所 |
|--------|-------|---------|
| C001 | 山田 | 東京 |
正規化のメリット
- データの重複が減り、DB の容量的に無駄がない
- データの更新をするときに、複数箇所を変更しなくて良い