第二正規形のテーブル
受注テーブル
伝票番号 | 日付 | 顧客コード |
---|---|---|
0129 | 2004/08/10 | 001 |
0157 | 2004/08/13 | 103 |
0248 | 2004/08/22 | 056 |
顧客コード | 顧客名 | 住所 | 市役所コード | 電話番号 |
---|---|---|---|---|
001 | A商事 | 横浜 | 012 | 045**** |
103 | B不動産 | 川崎 | 033 | 044**** |
2004/08/22 | C工業 | 藤沢 | 056 | 047**** |
伝票番号 | 商品コード | 数量 |
---|---|---|
0129 | Z101 | 200 |
0129 | N029 | 50 |
0157 | K403 | 40 |
0248 | N029 | 300 |
0248 | T110 | 120 |
0248 | Q200 | 870 |
商品コード | 単位 | 単価 |
---|---|---|
Z101 | cm | 1000 |
N029 | gallon | 3000 |
K403 | kg | 2000 |
T110 | dl | 9400 |
Q200 | l | 750 |
カンの良い人は気づいたかもしれませんが、市役所の電話番号は、市役所コードに関数従属していますよね。
市役所の電話番号は、顧客テーブルにおいて候補キーではないので、第二正規形にする過程では表が分割されなかったのですが、顧客コードが決まれば、市役所コードが決まり、市役所コードが決まれば、電話番号が決定する。このような状態を推移関数従属といいます。補足すると、三段論法で言うAはBである、BはCである、ゆえにAはCであるといったとき、CはAに推移関数従属しているのです。
第二正規形の推移関数従属を排除すると、第三正規形になるので、このBはCであるの部分を別表に分割します。すると以下のようなテーブル構成になります。
第三正規形のテーブル
受注テーブル
伝票番号 | 日付 | 顧客コード |
---|---|---|
0129 | 2004/08/10 | 001 |
0157 | 2004/08/13 | 103 |
0248 | 2004/08/22 | 056 |
顧客コード | 顧客名 | 住所 | 市役所コード |
---|---|---|---|
001 | A商事 | 横浜 | 012 |
103 | B不動産 | 川崎 | 033 |
2004/08/22 | C工業 | 藤沢 | 056 |
市役所コード | 電話番号 |
---|---|
012 | 045**** |
033 | 044**** |
056 | 047**** |
伝票番号 | 商品コード | 数量 |
---|---|---|
0129 | Z101 | 200 |
0129 | N029 | 50 |
0157 | K403 | 40 |
0248 | N029 | 300 |
0248 | T110 | 120 |
0248 | Q200 | 870 |
商品コード | 単位 | 単価 |
---|---|---|
Z101 | cm | 1000 |
N029 | gallon | 3000 |
K403 | kg | 2000 |
T110 | dl | 9400 |
Q200 | l | 750 |
これで、第三正規形の完成です。多くのシステムではここまで、正規化すれば実用レベルです。例えば市役所の電話番号が変わった場合、第二正規形では複数の電話番号を更新する必要がありますが、第三正規形まで行うと、電話テーブルの一つのレコードを更新するだけですみます。顧客の社名が変わる場合でも一箇所ですみます。商品が増えた場合も1レコードの追加です。この様な状態を一事実一箇所(1 fact in 1 place)といい、データの操作が最小の労力で行えます。効率が良いですね。
正規化の過程をざっと復習すると以下のような感じです。
・非正規形から第一正規形
繰り返しグループを排除ために、繰り返しグループとキーとなる項目で分割する。
・第一正規形から第二正規形
主キー以外のキー項目に関数従属しているものを分割する
・第二正規形から第三正規形
推移的に関数従属しているものを分割する。
以上の3ステップですね。
要注意:中には推移的関数従属が無い場合もあります。そのときは第二正規形にした時点で、第三正規形まで完了します。
さていよいよ次は過去問を解いてみましょう。