正規化 〜 One Fact in One Place 〜

  • 正規化とは (NF:Normal Form:正規形)

    正規化を行うということは、冗長なデータの排除、正しい従属関係の整備をすること。
    モデリングの原則 One Fact in One Place (1つの事実は、1つの所で)を行う。

正規化を行わないモデルには、データ操作を行うと不整合、損失、冗長(無駄)を伴う。

  • フィールド数が増加し(冗長)、格納領域を無駄に消費する。
  • 格納領域が大きいことで検索性能が低下する(キャッシュヒット)。
  • 1つのフィールド変更に対して複数箇所(レコード)のフィールド更新が必要。
  • 変更する対象の表が集中し、処理の分散化が行われない。
  • 1つのレコードの削除において保持しておきたい複数フィールドの情報を一緒に損失する。
  • 挿入を行うときに許可することができない登録が実行されてしまう(されては困る)。
    などの問題が発生する。

一方、(正規化を行ったモデルに対して)非正規化を行ったモデルには

  • カラムコピーにより結合処理を省き、検索性能が上昇する。
  • テーブル分割により更新の同時実行性能とキャッシュヒットが上昇する。
  • 導出項目の併設により計算効率の上昇。
    などの応答性能の向上を伴う点が多いのが特徴。(非正規化は整合性と応答性能のバランスをうまく調整する作業ということができる)

初期モデリングの段階で高速化を理由に、非正規化を行うのは誤りです。
まずは論理データモデリングに集中し、物理データモデリングを同時に行わないようにします。

例外として、例えば 7 桁の郵便番号と住所(都道府県)の共存は第 3 正規形ではありません。
といって、これを一旦 3NF にする人はいません。このような非正規化は、ほとんど検討する余地がないので省略しても問題ありません。

非正規形

  • 例) ある帳票(企業間取引)の資料からデータベース化を行うと仮定する。形式は以下
受注伝票
----------------------------------------
販売先名 : ○○○○○○   受注日 XXXXXX

明細
・販売品名  個数 価格(単価×個数)
・販売品名  個数 価格
----------------------------------------
  計              合計金額
  • 受注票 (非正規形)

    販売先名、受注日、販売品名1、数量1、価格1、購入品名2、数量2、価格2、合計金額

  • 都合上 同様に 入荷票や発注票 もあるとする

    卸元名、入荷日、入荷品名1、数量1、価格1、入荷品名2、数量2、価格2、合計金額

第1 正規化 (1NF)

  • エンティティに プライマリキー を設定。
  • 導出項目の除去
  • ビュー*1(帳票などの入手媒体形式)で繰り返し項目を除去する。
  • 関連するデータをまとめて個別のエンティティにする。
・非正規形
  [受注番号]、販売品名1、数量1、価格1、販売先名、受注日、合計金額
       販売品名2、数量2、価格2
↓
・第1 正規形
  [受注番号]、受注日、販売先名
     └ プライマリキー[受注番号]

  [受注番号、販売品名]、数量、単価
     └ 複合プライマリキー[受注番号、販売品名] (2レコードにして格納する)
  1. プライマリキー[受注番号]の生成
  2. 導出項目の除去 合計金額、価格
  3. 繰り返しグループ 販売商品1〜n の除去

第2 正規化 (2NF)

  • レコードがプライマリキー以外に従属しない関係にする (その壱)
    (プライマリキーの一部に従属するエンティティを独立させる)
  • 従属するエンティティを独立させ従属関係を結ぶ。
    (外部キーの設定)

商品名 ⇒ (受注票) 販売品名(複合プライマリキーの一部) ⇔ (入荷票) 入荷品名にも従属している状況

商品エンティティを作成

[商品コード]、商品名、単価

・第1 正規形
  [受注番号]、受注日、販売先名
  [受注番号、販売品名]、受注日、購入品名、個数、単価
    ↓
・第2 正規形
  [受注番号]、受注日、販売先名
  [受注番号、販売商品コード]、個数
  [商品コード]、商品名、単価
  1. プライマリキーの一部 販売品名のエンティティ化(商品エンティティ)

第3 正規化 (3NF)

  • レコードがプライマリキー以外に従属しない関係にする (その弐)
    (プライマリキー以外の従属するエンティティを独立させる)

販売先名 ⇒ (受注票) 販売先名 ⇔ (入荷票) 卸元名にも従属している

企業エンティティを作成

[企業コード]、企業名、(住所など)

・第2 正規形
  [受注番号]、受注日、販売先名
  [受注番号、販売商品コード]、個数
  [商品コード] 商品名、単価
 ↓
・第3 正規形
  [受注番号]、受注日、販売先企業コード
  [受注番号、商品コード]、個数
  [商品コード]、商品名、単価
  [企業コード]、企業名、(配送住所など)
  1. 販売先名の独立エンティティ化(企業エンティティ)


正規化の関連トピックス

日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ Oracle Web セミナー

*1 Oracle・スキーマオブジェクトのVIEWではない