第3正規形

データベース

第3正規形

まだ残っている関数従属性

たとえば、【科目】に担当講師の情報を追加することを考えます。

科目(科目ID、科目名、担当講師ID、担当講師名、内線番号)

これで必要な情報を格納できているように見えます。

【科目】の主キーは『科目ID』1つだけなので、この表に属性をいくら追加しても第2正規形の条件を満たしています。しかし『沖田の内線番号は0013』という情報が2回だぶって登録されていて、いかにも能率が悪そうです。

確かにすべての非キー属性が主キーに完全関数従属しているのですが、よく見ると

担当講師ID → (担当講師名、内線番号)

という、主キー以外の部分にも関数従属が存在します。これを別の表に移した方がスッキリしそうです。

推移的関数従属

ある関係スキーマ/テーブルにおいて、

1. X → Y である
2. Y → X ではない
3. Y → Z である

の3つがすべて成立しているとき、 

『ZはXに推移的関数従属している』

といいます。

この『推移的関数従属』という概念を使って、テーブルの設計のための条件を追加します。

『すべての非キー属性が、主キーに対して推移的関数従属しない』

第二正規形の条件を満たし、かつこの新しい条件も満たす表を『第3正規形』といいます。

第3正規形への分割

この例の場合、

科目ID → 担当講師ID
担当講師ID → 科目ID ではない
担当講師ID → (担当講師名、内線番号)

となっていますので、(担当講師名、内線番号)は『科目ID』に対して推移的関数従属している、といえます。つまりこの表は第2正規形ではあっても、第3正規形ではありません。

第3正規形にするには、推移的関数従属している属性を他の表に移す必要があります。
この例の場合は『担当講師ID』『担当講師名』『内線番号』の3つの属性からなる新たな表をつくり、【科目】からは推移的関数従属していた非キー属性である『担当講師名』と『内線番号』を削除します。

新たに作る表の名前は【講師】としましょう。
また、属性名も若干変更して
担当講師ID』ではなく『講師ID
担当講師名』ではなく『講師名
とします。

講師ID → (講師名、内線番号)

が成り立っていますから、主キーは『講師ID』とします。
よって、新たな関係スキーマ/テーブルは以下のようになります。

講師(講師ID、講師名、内線番号)

また、【科目】は以下のようになります。

科目(科目ID、科目名、担当講師ID)

これで、【科目履修状況】が第三正規形まで正規化できました。

正規化しないことによる問題点

第三正規形にする前の【科目】をもう一度みてみましょう。

矛盾を避ける

科目(科目ID、科目名、担当講師ID、担当講師名、内線番号)

このテーブルでは、
『担当講師ID=T01は、担当講師名=沖田、内線番号=0013である』
というデータが2回記録していて無駄だ、という点は既に指摘しましたが、それ以上に問題なのが

のようなデータが記録できてしまうことです。
1行目と2行目の情報は、ともに『T01、沖田』の情報のはずですが、内線番号が異なり、矛盾が生じています。同じデータを複数回記録するというのは、単に無駄というわけではなく、入力間違いや更新漏れによって、このような矛盾を発生させる原因となるのです。

第三正規形に分割後は、

講師(講師ID、講師名、内線番号)

『沖田の内線番号は0013』という情報は【講師】の中の1行にしか書かれていないため、このような矛盾は生じません。このように、正規化によって『同じ内容があちこちに書かれていないようにすること』を

『一事実一箇所の法則』

といい、データベース設計時の重要な注意点です。

データ挿入可能

もう1つ、正規化しない構造には致命的な欠点があります。
正規化前の【科目】の主キーは『科目ID』のため、『科目ID』には空欄が許されません。
つまり、ある講師の内線番号を記録するためには、その講師が何らかの科目を担当し、かつ科目IDが確定していなければならないのです。
もちろん正規化して【講師】を別の関係スキーマ/テーブルとすればこのようなことはありません。

練習問題4

次の表は、練習問題3で第二正規形にした表です。これらを第三正規形にしなさい。

売上(売上ID、会員ID、氏名、住所)

商品(商品ID、商品名、単価)

売上明細(売上ID商品ID、個数)

コメント

タイトルとURLをコピーしました