以上説明した第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)に戻る
ホームページに戻る