2009年9月18日

[mysql 15022] DBをどこまで正規化すべきか?

プログラム歴は結構長いですが、SQLはかなり初心者です。

DBの設計をしているのですが、参考書などには必ず正規化の事が載っています。
たとえばその中で、「計算で求められる事を項目にしない」ってのがあります。
「導出フィールドの削除」って書いてあります。
『商品単価×数量で合計が求められるから、合計の項目は不要』というヤツです。
で、私が持っている本を読むと確かにそう書いてあるのですが、
必ずしもそれが正しいのだろか?と疑問に思っています。


例えば、数種類のジャムの販売のDBを作る場合、
顧客テーブル、受注履歴テーブル、注文明細テーブル、商品テーブル
を考えたとします。
受注履歴は、1販売毎に1レコード。
その受注IDを持つ注文明細テーブルが複数あり、それが商品テーブルIDと
数量を持つとします。

■具体的には
2種類のジャムを、それぞれ2個、1個買ったとすると…
・受注テーブル1件(受注ID)
001
・注文明細が2件(受注ID,明細ID,商品ID,数量)
001,01,A,2
001,02,B,1
・商品テーブル(商品ID,名前,単価)
A,りんごジャム,100
B,いちごジャム,70
だと、受注ID=001の合計額は
100*2+70=170円となります。

これが、数千レコード分を一覧表で出そうとすると、全て単価×数量を
計算しないと出せないワケですよね。
しかし、受注テーブルに合計があれば、簡単に出せます。
SQL文を書いてしまえば、簡単も複雑も関係ないでしょうが、
これって、DBのサイズを優先するか、SQLの実行時間を優先するか?
って事で選ぶので良いのでしょうか?

当然、注文明細を操作した場合は、受注テーブルの金額を書き直す事を
厳守する必要がありますし、商品単価も変更しないという前提が必要ですが。
(商品単価は今後の価格改定の可能性を考えると、注文明細に覚えこまして
しまうべきなんですよね?)

本を読んでると、正規化は正義のような書き方をしているような感じもしますが、
本来しなくてもいいようなレベルの事でも、本では説明をする為に、正規化を
しているような気がするのです。
例えば、上記のようなテーブル例の場合はどうなんでしょうか?
私は、受注テーブルに合計を覚えるほうが良いと思うのですが…

消費税なんかも悩ましいところです。
計算で出せますが、今後税率が変わった場合、レコードの作成時期によって
税率を変えるのはかなり非効率だと思うのですが。
そうなると、小計、税額、合計を覚える必要があるって事になりますよね?

なんだか、1つの質問で長々と書いてしまいましたが、どなたかアドバイスお願
いします。


他にも、郵便番号を123-456と覚えていた場合、
2345や12-345の文字列で検索した場合でも類似として検索できるように、
表示用フィールド('123-456')と検索用フィールド('123456')の
両方を覚えて、検索するときは数字のみにした値を、検索用フィールド
に対して検索させています。
確かに、検索するたびにSQLで'-'を抜いたフィールドを作る事も可能だと
思いますが、検索用フィールドを常に別で持つのは、古いDBの
考え方なのでしょうか?

--
わたせ <watase@xxxxx>

投稿者 xml-rpc : 2009年9月18日 00:00
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/88639
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。