💽

DB 正規化について

2024/06/11に公開

正規化とは

データベース設計においてデータの冗長性を減らし、一貫性と効率性を向上させるためのプロセス

これを達成するために、データを複数の関連性のあるテーブルに分割し、各テーブルが特定のデータのみを含むように設計します。

簡単にいうと

  • データの冗長性を減らす
    重複するデータを排除することで、データベースのサイズを縮小し、データ管理を簡単にします。
  • データの一貫性を保つ
    データの更新、挿入、削除の際にデータの一貫性を保つことで、データの整合性を確保します。
  • データの異常を防ぐ
    更新異常、挿入異常、削除異常といったデータ操作時の問題を防ぎます。

悪いDBの例

元のテーブル

顧客ID 顧客名 住所 商品ID 商品名 価格 注文日
1 山田太郎 東京市中央区1-1 101 ノートパソコン 100,000 2024-06-01
2 佐藤花子 横浜市西区2-2 102 スマートフォン 80,000 2024-06-02
1 山田太郎 東京市中央区1-1 103 タブレット 50,000 2024-06-03
  • データの重複

    • 「山田太郎」の情報が複数行にわたって重複しています。住所も同様です。
    • これにより、データベースのサイズが大きくなり、無駄なスペースを消費します。
  • 更新異常
    例えば、山田太郎の住所が変更になった場合、全ての該当行を更新する必要があります。一つでも更新し忘れると、データの一貫性が失われます。

  • 挿入異常
    新しい商品を追加したいが、顧客IDや住所など、他の情報も一緒に挿入しなければならない場合があります。

  • 削除異常
    例えば、特定の商品を削除したい場合、その商品に関連する顧客情報も一緒に削除されるリスクがあります。

正規化したDBの例

顧客テーブル

顧客ID 顧客名 住所
1 山田太郎 東京市中央区1-1
2 佐藤花子 横浜市西区2-2

商品テーブル

商品ID 商品名 価格
101 ノートパソコン 100,000
102 スマートフォン 80,000
103 タブレット 50,000

注文テーブル

顧客ID 商品ID 注文日
1 101 2024-06-01
2 102 2024-06-02
1 103 2024-06-03

改善点

データの重複がなくなる:

  • 顧客の情報は顧客テーブルに一度だけ保存されます。商品情報も同様です。

更新が簡単になる:

  • 顧客情報や商品情報の更新は一つの場所で済みます。

挿入が簡単になる:

  • 新しい商品を追加する際に、関連する他の情報を一緒に挿入する必要がありません。

削除が安全になる:

  • 商品を削除しても、顧客情報には影響を与えません。

正規化の段階

正規化は段階的に行われ、各段階を「正規形」と呼ぶ

第一正規化の条件

  1. 各列が単一の値のみを持つこと:
    • 各セルに複数の値を入れないようにします。各セルには分割できない一つの値だけを入れます。
  2. 各行が一意の識別子(主キー)を持つこと:
    • 各行は一意に識別できる必要があります。これには、主キー(Primary Key)を設定することが一般的

非正規化の例

例えば、以下のようなテーブルがあるとします:

顧客ID 顧客名 電話番号
1 山田太郎 123-4567, 234-5678
2 佐藤花子 345-6789

このテーブルでは、電話番号が複数の値を持っています。これは第一正規化の条件に反しています。

第一正規化の適用

1NFを満たすために、電話番号を別々の行に分割します:

顧客ID 顧客名 電話番号
1 山田太郎 123-4567
1 山田太郎 234-5678
2 佐藤花子 345-6789

第二正規化の条件

  1. 第一正規化 (1NF) を満たしていること:
    • すべての属性が単一の値を持つ。
  2. 部分関数従属性を排除すること:
    • 複合主キー(複数の列で構成される主キー)の一部にのみ依存する属性を分離します。

非正規化の例

まず、以下のようなテーブルを考えてみます:

注文ID 商品ID 顧客名 商品名 数量 価格
1 101 山田太郎 ノートパソコン 1 100,000
2 102 佐藤花子 スマートフォン 2 80,000
3 101 山田太郎 ノートパソコン 1 100,000

このテーブルでは、注文ID商品ID が複合主キーです。しかし、商品名価格商品ID のみに依存しています。これは部分関数従属性です。

第二正規化の適用

部分関数従属性を排除するために、テーブルを次のように分割します:

注文テーブル:

注文ID 顧客名 商品ID 数量
1 山田太郎 101 1
2 佐藤花子 102 2
3 山田太郎 101 1

商品テーブル:

商品ID 商品名 価格
101 ノートパソコン 100,000
102 スマートフォン 80,000

このようにテーブルを分割することで、商品名価格商品ID にのみ依存することが保証され、部分関数従属性が排除されます。

第三正規化の条件

  1. 第二正規化 (2NF) を満たしていること:
    • すべての部分関数従属性が排除されている。
  2. 推移的関数従属性を排除すること:
    • 非キー属性が他の非キー属性に依存しないこと。

例と説明

第二正規化されたテーブル

注文テーブル:

注文ID 顧客名 商品ID 数量
1 山田太郎 101 1
2 佐藤花子 102 2
3 山田太郎 101 1

商品テーブル:

商品ID 商品名 価格
101 ノートパソコン 100,000
102 スマートフォン 80,000

推移的関数従属性の問題

顧客名注文テーブル に含まれていますが、顧客ID が無いため、顧客情報が重複している可能性があります。これを解決するために、顧客情報を別のテーブルに分けます。

第三正規化の適用

注文テーブル:

注文ID 顧客ID 商品ID 数量
1 1 101 1
2 2 102 2
3 1 101 1

顧客テーブル:

顧客ID 顧客名 住所
1 山田太郎 東京市中央区1-1
2 佐藤花子 横浜市西区2-2

商品テーブル:

商品ID 商品名 価格
101 ノートパソコン 100,000
102 スマートフォン 80,000

まとめ

今回データベースの基礎として、正規化について学びました。
自分自身も以前正規化について学びましたが、ぼんやり忘れている節があったので
悪い例といい例を見ながら比較することで、復習することができました!
そこの部分もユースケースに応じてどこまで正規化をする必要があるかなども
別の記事で紹介していきます!!!

Discussion