情報の正規化について解説します


1.正規化とは何か
 リレーショナルデータベースにおいてはデータ構造を表の形式で表現します。
 そこには各表に無駄なデータを持たさず(冗長度を減らす)、関連性の強いデータ群だけをまとめることによってデータの独立性を高め、部品化した各表を組み合わせることによって各アプリケーションに必要なデータを提供しようといいますねらいがあります。
 この場合、表中のデータを変更した場合にデータ間に矛盾が生じることがありますが、これを更新不整合といいます。
 正規化とはこのような目的からデータ構造についてデータの冗長性を少なくし、かつ 更新不整合が起こらないようにしていく作業をいうのです。

2.正規化の種類
 正規化には第1正規形、第2正規形、第3正規形、ボイスコッド正規形、第4正規形、第5正規形の六つの種類があり、それぞれの正規形は全社を包含します関係になっています。
 各正規形の定義は以下のとおりです。

(1)第1正規形
 第1正規形とは、表において、属性の値として繰り返しなどの集合や複合値を持たない表をいいます。

(2)第2正規形
 第2正規形とは表が第1正規形であり、かつすべての非キー属性が主キーに対して完全関数従属である場合の表をいいます。
 ここで主キーとは表中の要素を特定できる属性の組み合わせを指します。それが複数存在します場合は候補キーといい、その中で最も冗長性の低いものを主キーとして選択することになります。
 完全関数従属とはある属性(X)の値を定めると、他の属性(Y)の値が位置的に定まるとき、YはXに関数従属であるといい、X→Yと表記します。
 その際にXのいかなる真部分についても関数従属性が成り立たない場合、つまりXが関数従属性を成り立たせる最小の属性集合である場合を完全関数従属の状態といいます。
 Xのうちの真部分とはXが複数の部分に分割できる場合を考えます。
 たとえばA、B、Yという属性があってB→Cであるときに、AとBとの組み合わせをXとするとX→Yとなりますが、XのうちのBすなわちXの真部分と関数従属性が成り立ちます。
 Yからみた場合、Aの部分については冗長な関係にあることになるのです。

(3)第3正規形
 第3正規形とは表が第2正規形であり、かつすべての非キー属性が推移的に関数従属でない表をいいます。
 推移的に関数従属であるとは属性X、Y、Zがあって「X→YでかつY→Xでない、そしてY→Zである」であるときに「X→Z」が得られるように、既存の関数従属から新たな関数従属を得られる状態をいいます。

(4)ボイスコッド正規形
 ボイスコッド正規形とは他の属性がある属性(X)に完全関数従属である場合に、かつ属性(X)が候補キーであるとき、この表をボイスコッド正規形といいます。

(5)第4正規形
 第4正規形とはボイスコッド表で、すべての適切な多値従属性がキーによるものである表をいいます。

(6)第5正規形
 分解によって得られる表が結合によって、もとの表に戻ることが可能であることを結合従属性といい、ある表がその候補キー内で結合従属性が満足されている場合を第5正規形といいます。

3.正規化の実際
 以上説明した第1から第5までの正規化について具体的なデータベース設計をつうじて説明してみましょう。
 事例としてとりあげているのは商品管理業務であり、実際にリレーショナルデータベースを用いた情報システムの構築が行われたものです。

(1)非正規形
 まず、商品管理に必要となるデータについて考えてみますと、以下のものがあげられます。
(ただし、ここでとりあげたデータは正規化解説のために、実際に必要となるデータのうちから一部のみを取り上げたものです。)
 これらのデータはまだ繰り返し部分をふくんでいたり、何度も同じ項目が出現したりと多くの冗長性を有しています。

<商品データ>
 商品コード、商品名、部門コード、部門名、大分類コード、大分類名、中分類コード、中部門名、小分類コード、小分類名、プライスライン、ブランドコード、ブランド名、売価履歴(店舗コード、店舗名、年月日別)、原価、仕入先コード、仕入先名、契約数量、発注ロット数、メーカーコード、メーカー名、倉庫コード、倉庫名、シーズンコード、シーズン名、セット単位数、タグ作成区分、補充発注区分、追加発注限度額、担当者コード、担当者名

(2)第1正規形
 ここに取り上げた五つの非正規化データについて順に正規化をすすめていくことにしましょう。
 まず、はじめに行うべきことは第1正規化です。
 第1正規化とは先に述べたように表の中で属性の値として繰り返しなどの集合や複合値を排除することです。
 商品データについてみてみると、売価履歴(店舗コード、店舗名、年月日別)となっており、これが繰り返し項目となっていることがわかります。具体的には以下のような表イメージになります。

 ---------------------------------------------------------------------------
 商品コード、商品名、・・・売価履歴(店舗コード、店舗名、年月日、売価)、原価、・・・
 ---------------------------------------------------------------------------
 000120001 無地紺Tシャツ・・・  (101   北大宮 95/06/05 1900
                 101   北大宮 95/07/10 1500
                 101   北大宮 95/09/26 0980
                 102   南大宮 95/06/05 1900
                 102   南大宮 95/07/12 1500
                 102   南大宮 95/06/04 0980) 0800 ・・・
 --------------------------------------------------------------------------
 000120002  自動車柄Tシャツ ・・・ (101   北大宮 95/06/05 2900
                 101   北大宮 95/07/10 2500
                 101   北大宮 95/09/26 1900
                 102   南大宮 95/06/05 2900
                 102   南大宮 95/07/12 2500
                 102   南大宮 95/06/04 1800) 1100 ・・・
                 ・
                 ・
                 ・

 商品データに対して行う第1正規化の具体的な作業は、売価についての繰り返し部分を排除するように繰り返し部分に対応するその他の項目について値を入れることになります。
 その結果、表のイメージは次のようになるはずです。

  ---------------------------------------------------------------------------
  商品コード、  商品名、  ・・ 店舗コード、店舗名、年月日、 売価、原価、・・・
  ---------------------------------------------------------------------------
  000120001  無地紺Tシャツ     101    北大宮 95/06/05 1900 0800 ・・・
  --------------------------------------------------------------------------
  000120001  無地紺Tシャツ     101    北大宮 95/07/10 1500 0800 ・・・
  --------------------------------------------------------------------------
  000120001  無地紺Tシャツ     101    北大宮 95/09/26 0980 0800 ・・・
  --------------------------------------------------------------------------
  000120001  無地紺Tシャツ     102    南大宮 95/06/05 1900 0800 ・・・
  --------------------------------------------------------------------------
  000120001  無地紺Tシャツ     102    南大宮 95/07/12 1500 0800 ・・・
  --------------------------------------------------------------------------
  000120001  無地紺Tシャツ     102    南大宮 95/06/04 0980 0800 ・・・
  --------------------------------------------------------------------------
  000120002  自動車柄Tシャツ    101    北大宮 95/06/05 2900 1100 ・・・
  --------------------------------------------------------------------------
  000120002  自動車柄Tシャツ    101    北大宮 95/07/10 2500 1100 ・・・
  --------------------------------------------------------------------------
  000120002  自動車柄Tシャツ    101    北大宮 95/09/26 1900 1100 ・・・
  --------------------------------------------------------------------------
  000120002  自動車柄Tシャツ    102    南大宮 95/06/05 2900 1100 ・・・
  --------------------------------------------------------------------------
  000120002  自動車柄Tシャツ    102    南大宮 95/07/12 2500 1100 ・・・
  --------------------------------------------------------------------------
  000120002  自動車柄Tシャツ    102    南大宮 95/06/04 1800 1100 ・・・
                 ・
                 ・
                 ・

(3)第2正規形
 第1正規形では、データの変更上で注意が必要となります。
 たとえば、商品名を変更する場合、データの一貫性のために同じ商品コードを持つデータについて全て変更しなければなりません。もし、一データのみ変更してしまうと一貫性がなくなってしまいます。
 これを更新不整合といいます。
 そこで、こうした第1正規形の持つ問題点を解決するために第2正規形への変形を行うことになるのです。
 第2正規形とは第1正規形のデータについて、すべての非キー属性が主キーに対して完全関数従属になるようにすることです。
 では商品データに対してみてみましょう。
 表中の要素を特定する主キーを考えてみると、売価は商品コード+店舗コード+年月日の組み合わせ、店舗名は店舗コードとなり、その他の属性は商品コードだけを主キーとしますことで特定できることがわかります。
 つまり、店舗コード、店舗名、年月日、売価以外の属性については商品コードについて完全関数従属の関係が成り立ち、売価だけは商品コードと店舗コード、年月日の組み合わせ、店舗名は店舗コードに対して完全関数従属の関係となるのです。
 したがって、これらの関係にしたがって表を分割すれば第2正規形が成立します。
 その結果、表のイメージは次のようになります。

  --------------------------------------
  商品コード、  商品名、  ・・ 原価、・・・
  --------------------------------------
  000120001  無地紺Tシャツ    0800 ・・・
  --------------------------------------
  000120002  自動車柄Tシャツ   1100 ・・・
                 ・
                 ・
                 ・

  -------------------------------------
  商品コード、 店舗コード、年月日、売価
  -------------------------------------
  000120001  101    95/06/05 1900
  -------------------------------------
  000120001  101    95/07/10 1500
  -------------------------------------
  000120001  101    95/09/26 0980
  -------------------------------------
  000120001  102    95/06/05 1900
  -------------------------------------
  000120001  102    95/07/12 1500
  -------------------------------------
  000120001  102    95/06/04 0980
  -------------------------------------
  000120002  101    95/06/05 2900
  -------------------------------------
  000120002  101    95/07/10 2500
  -------------------------------------
  000120002  101    95/09/26 1900
  -------------------------------------
  000120002  102    95/06/05 2900
  -------------------------------------
  000120002  102    95/07/12 2500
  -------------------------------------
  000120002  102    95/06/04 1800
                 ・
                 ・
                 ・

  ------------------
  店舗コード、店舗名
  ------------------
   101    北大宮
  ------------------
   102    南大宮
      ・
      ・
      ・

(4)第3正規形
 次に作成した第2正規形についてみてみると、ここでもまだ更新不整合が生じます。
 たとえば、部門名を変更する場合、データの一貫性のために同じ部門名を持つデータについて全て変更しなければなりません。
 もし、一データのみ変更してしまうと一貫性がなくなってしまいます。
 同じことが、大分類名、中部門名、小分類名、ブランド名、仕入先名、メーカー名、倉庫名、シーズン名、担当者名についてもあてはまります。
 これらの不整合は推移関数従属の関係の存在によって起こるものであり、これを除去する必要があります。先にあげた各項目について推移関数従属の関係を整理しますと以下のとおりとなります。

 @商品コード→部門コード→部門名
 A商品コード→大分類コード→大分類名
 B商品コード→中分類コード→中分類名
 C商品コード→小分類コード→小分類名
 D商品コード→ブランドコード→ブランド名
 E商品コード→仕入先コード→仕入先名
 F商品コード→メーカーコード→メーカー名
 G商品コード→倉庫コード→倉庫名
 H商品コード→シーズンコード→シーズン名
 I商品コード→担当者コード→担当者名

 第2正規形から、こうした推移関数従属関係を除去すると第3正規形が得られます。
 その結果、表のイメージは次のようになります。

  --------------------------------------------------------------------------
  商品コード、  商品名、 部門コード、大分類コード、中分類コード、小分類コード
  プライスライン、ブランドコード、原価、仕入先コード、契約数量、発注ロット数
  メーカーコード、倉庫コード、シーズンコード、セット単位数、タグ作成区分、 
  補充発注区分、追加発注限度額、担当者コード                
  --------------------------------------------------------------------------
  000120001  無地紺Tシャツ  A     1       01      001   
    3        12     0800  111     450000    50000  
   015       1A       4       10      8     
    0      100000      401                   
  --------------------------------------------------------------------------
  000120002  自動車柄Tシャツ A     1       01      002   
    3        12     1100  111     400000    50000  
   015       1A       4       10      8     
    0      100000      410                   

  -----------------------
  部門コード、部門名   
  -----------------------
    A    一般   
    B    オリジナル
    C    インポート

  -----------------------
  大分類コード、大分類名 
  -----------------------
    1    カジュアル
    2    紳士   
    3    レディス 

  -----------------------
  中分類コード、中分類名 
  -----------------------
    01    シャツ  
    02    トレーナー
    03    ポロシャツ

  ---------------------------
  小分類コード、小分類名   
  ---------------------------
    001    半袖無地シャツ 
    002    半袖柄シャツ  
    003    長袖無地シャツ 

  ---------------------------
  ブランドコード、ブランド名 
  ---------------------------
    01      AAAA   
    02      BBBB   
    03      CCCC   

  ---------------------------
  仕入先コード、仕入先名   
  ---------------------------
    001    東京商店   
    002    大阪商会   
    003    名古屋流通  

  ---------------------------
  メーカーコード、メーカー名 
  ---------------------------
    001    日本衣料   
    002    米国産業   
    003    中国製造   

  ---------------------------
  倉庫コード、倉庫名     
  ---------------------------
    01    北倉庫    
    02    南倉庫    
    03    西倉庫    

  ---------------------------
  シーズンコード、シーズン名 
  ---------------------------
     1      春    
     2      夏    
     3      秋    
     4      冬    

  ---------------------------
  担当者コード、担当者名   
  ---------------------------
    001     田中太郎 
    002     山本次郎 

(5)ボイスコッド正規形
 第3正規形になっても更新不整合が含まれる場合があります。
 先の例において一つの商品に対して複数の仕入先が存在するとします。また、仕入先ごとに担当者が決められているとします。
 この場合、売価履歴と同じように繰り返し項目である仕入先コード、仕入先名、担当者コードについて第1正規化、第2正規化、第3正規化と順に正規化を行ったとすると次の表が新規に分割されるはずです。

 --------------------------------------
 商品コード、仕入先コード、担当者コード
 --------------------------------------
  000120001   111      401   
 --------------------------------------
  000120001   112      402   
 --------------------------------------
  000120002   111      401   
 --------------------------------------
  000120002   150      403   

  ---------------------------
  仕入先コード、仕入先名   
  ---------------------------
    001    東京商店   
    002    大阪商会   
    003    名古屋流通  

 商品コード、仕入先コード、担当者コードを属性とする上の表は、繰り返し部分を持たず、また商品コード+仕入先コード、あるいは商品コード+担当者コードをキーとすることができ、かつ推移従属の関係が存在しないため、第三正規形です。
 しかし、この表において、もし担当者401氏が担当する仕入先112から仕入れている商品が000120001だけだったとすると、その商品が削除された場合、担当者401氏が仕入先112を担当するというデータも削除されてしまいます。
 また、実際に商品が仕入れられるまで新しい仕入先と担当者を登録することができません。
 あるいは商品000120001の仕入先112の担当者を403に変更すると、402氏が仕入先112を担当するという事実まで削除されてしまうのです。
 このような更新不整合が生じるのは、仕入先コードを決定するものとして担当者コードが候補キーとなっていないからです。そこで、仕入先コードと担当者コードの関係について以下のように新規分割することによって、こうした更新不整合が起きなくなります。

 ------------------------
 商品コード、仕入先コード
 ------------------------
  000120001   111   
 ------------------------
  000120001   112   
 ------------------------
  000120002   111   
 ------------------------
  000120002   150   
 ------------------------

 --------------------------
 担当者コード、仕入先コード
 --------------------------
   401      111   
 --------------------------
   402      112   
 --------------------------
   403      150   
 --------------------------

 この分割によって得られた新しい表においては、他の属性がある属性(X)に完全関数従属である場合に、かつ属性(X)が候補キーであるというボイスコッド正規形の条件を満たすものとなっています。
 ボイスコッド正規化を施す前の段階では、仕入先コードが担当者コードに完全関数従属であるにもかかわらず、担当者コードが候補キーとなっていなかったことに注意して下さい。

(6)第4正規形
 次に、ボイスコッドの正規形の条件を満たしていてもまだなお更新不整合の生じる場合について考えてみましょう。
 また先にあげた例において、今度は商品を補完する倉庫が複数ある場合を想定してみます。
 その場合、商品がどこから仕入されてどこに補完されるかを管理するため、以下の表を作成したとします。

 ------------------------------------
 商品コード、仕入先コード、倉庫コード
 ------------------------------------
  000120001   111     1A   
 ------------------------------------
  000120001   111     3B   
 ------------------------------------
  000120001   112     1A   
 ------------------------------------
  000120002   111     3C   
 ------------------------------------
  000120002   150     2A   
 ------------------------------------

 ここで作成された上記の表は商品コード、仕入先コード、倉庫コードの三つの属性の組み合わせを候補キーとすることができるボイスコッド正規形の条件を満たす形式となっています。
 しかし、商品コードに複数の仕入先コードと複数の倉庫コードが対応している多値従属の形となっています。
 この場合の更新不整合として、商品コードと新しい仕入先コードが決定されても、倉庫コードが決まらないと登録できない状態が発生します。
 こうした更新不整合の原因は仕入先コードと倉庫コードというそれぞれ独立した関係があるからでもなく、多値従属の属性があるからでもありません。
 独立した属性が存在し、かつ多値従属の属性があることによるのです。
 そこで、この表から独立した多値従属性の属性を除去することによって、こうした更新不整合を解決することができます。
 このようにしてボイスコッドの正規化の条件を満たした表を分割してできる表を第4正規形といいます。

 ------------------------
 商品コード、仕入先コード
 ------------------------
  000120001   111   
 ------------------------
  000120001   112   
 ------------------------
  000120002   111   
 ------------------------
  000120002   150   
 ------------------------

 ----------------------
 商品コード、倉庫コード
 ----------------------
  000120001   1A   
 ----------------------
  000120001   3B   
 ----------------------
  000120002   3C   
 ----------------------
  000120002   2A   
 ----------------------

(7)第5正規形
 最後に第5正規形について考えてみます。
 第5正規形は第4正規形を満たした状態でなおかつ更新不整合が生じる場合を考えることになります。
 今、例にあげた商品データとは別に仕入先データについて以下のような管理をする表を作成したとします。

 ------------------------------------------
 仕入先コード、メーカーコード、小分類コード
 ------------------------------------------
   111      015      001
   111      021      019
   111      036      019
   112      015      001
   112      021      001

 この表ではどこの仕入先がどこのメーカーのどんな商品を扱っていますのかを管理しています。
 そして、この表においては仕入先コード+メーカーコード、小分類コードが主キーであり、推移従属の関係も独立した多値従属の属性もないため、第4正規形であるといえます。
 実はこの表においても更新不整合が生じるのです。
 たとえば仕入先コード112からの仕入をやめたとする、メーカーコード021が小分類コード001の商品を製造しているというデータまで削除されてしまいます。

 そこで、まず以下のような二つの表に分割します。

 ----------------------------
 仕入先コード、メーカーコード
 ----------------------------
   111      015    
   111      021    
   111      036    
   112      015    
   112      021    

 --------------------------
 仕入先コード、小分類コード
 --------------------------
   111      001   
   111      019   
   112      001   

 ここで分割した二つの表には問題があります。
 これら二つの表を結合した場合、以下のように元の表に存在しないデータが発生してしまうのです。

 ------------------------------------------
 仕入先コード、メーカーコード、小分類コード
 ------------------------------------------
   111      015      001
   111      015      019 *
   111      021      001 *
   111      021      019
   111      036      001 *
   111      036      019
   112      015      001
   112      021      001  (*部分が元の表に存在しないデータ)

 そこで、この表をさらに以下の三つの表に分解することによって、こうした更新不整合を除去することができるのです。

 ----------------------------
 仕入先コード、メーカーコード
 ----------------------------
   111      015    
   111      021    
   111      036    
   112      015    
   112      021    

 --------------------------
 仕入先コード、小分類コード
 --------------------------
   111      001   
   111      019   
   112      001   

 ----------------------------
 メーカーコード、小分類コード
 ----------------------------
   015      001
   021      019
   036      019
   021      001

 このようにして分解して得られた表は結合すると、もとの表に戻ることが可能である結合従属性を持っており、こうした結合従属性が満足されている場合を第5正規形というのです。

 以上、第1正規形から第5正規形までの変形についてみてきました。
 実際の正規化についてはボイスコッドの正規化までの作業で十分であり、その結果について多値従属性や結合従属性といった例外状況がないか検査することになるでしょう。

情報化ヒント集(Tips)に戻る情報化ヒント集(Tips)に戻る
ホームページに戻る ホームページに戻る