SQL攻略 - Web上でSQLを実行しながらマスターするサイト
English ver [3 From non-normal form to first normal form] is here.
ホーム >> 正規化攻略 - 非正規形から第一正規形へ

非正規形から第一正規形へ

繰り返しグループを、分割して排除しよう。

さていよいよ正規化の本題に突入します。ここでは過去に出題されたの問題を例に、正規化を解説します。(若干手を加えています)

問題
 次のような繰返し構造をもったレコードからなるデータを,第3正規形に正規化せよ。ここで,下線部分は主キーを表す。また,単位と単価は商品コードごとに決まるものとする。またこの会社が取り扱っている商品は危険物であるため、購入先の市役所に電話連絡することが義務付けられている。

非正規化状態の表

伝票
番号
日付顧客
コード
顧客名住所市役所
コード
電話
番号
商品
コード
単位数量単価
01292004/08/10001A商事横浜012045****Z101
N029
cm
gallon
200
50
1000
3000
01572004/08/13103B不動産川崎033044****K403kg402000
02482004/08/22056C工業藤沢056047****N029
T110
Q200
gallon
dl
l
300
120
870
1000
9400
750

非正規化状態の表を無理やりRDBのテーブルにするとこうなります。商品コードから単価までに番号を振って1~3まで定義しています。この状態は問題です。

さて何が問題か?

顧客はテーブルに定義されている数以上の、商品を購入することができない。

ここでは3まで定義しているので、顧客はは商品を4つ以上は購入できないことになります。じゃあ通常考えられるだけ数をのテーブル定義すればいいかといえば、当然そんなことはなくて、膨大な領域が無駄になります。(しかもSQLでまともに扱えない。)

そこで、ちゃんと正規化する必要が出てきます。まず非正規化からの第一歩である、第一正規形にしてみましょう。商品コードから 単価までの項目のように、同じ項目が繰り返しているものを、繰り返しグループといいますが、この繰り返しグループをなくしてやると第一正規形の完成です。

繰り返しグループの排除をは、繰り返している項目を別表に分割して別表にすると完了です。その際にリレーションが失われないように注意をしなくてはなりません。例えば、繰り返している項目だけを別表にすると、誰が何を購入したのかがわからなくなりますよね。そのため、従属する項目(ここでは主キー)を付けて別表にしています。

第一正規形のテーブル

伝票番号日付顧客コード顧客名住所市役所コード電話番号
01292004/08/10001A商事横浜012045****
01572004/08/13103B不動産川崎033044****
02482004/08/22056C工業藤沢056047****

伝票番号商品コード単位数量単価
0129Z101cm200
1000
0129N029gallon50
3000
0157K403kg402000
0248N029gallon3001000
0248T110dl1209400
0248Q200l870750

これで、顧客はテーブルの定義に制限されること無く、商品を購入することができるようになりました。レコードをどんどん追加していけばOKです。