商品情報のデータベースを作成しています。
商品には色やサイズのバリエーションがあるのでテーブルを「商品情報」「バリエーション情報」にわけました。
テーブル項目は以下とします。
■商品情報(item)
id
item_name
item_price
■バリエーション情報(variation)
id
item_id
color
size
商品情報には画像を登録したいので「画像」テーブルを追加します。
■画像(image)
id
item_id
variation_id
image_name
comment
商品はバリエーションがなくても1つのバリエーションの商品として登録されるのでimage_idとvariation_idで結合しています。
このテーブル構成で商品共通の画像も登録したいという要望があり、画像テーブルをどう結合するのが適当なのかを質問したいです。
とりあえず共通画像は画像テーブルのvariation_idを-1で登録するルールとし、今のところ問題なく動いているように思えます。
ただ、この様なデータの持ち方で今後問題が発生しないのか経験不足のため自信がありません。
もしもプログラムで困ることがあるとか、もっといいデータの持ち方がある等ありましたらアドバイスいただけると幸いです。
よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ベストアンサー
この様なデータの持ち方で今後問題が発生しないのか
私は、'画像'と'商品共通の画像'を同じテーブルで表現する方法には問題がある、と考えます。
なぜなら、この方法では'バリエーション'と'画像'の間に外部キー制約を使用できないからです。
外部キー制約が使用できないと、整合性のないデータがDBに登録されてしまうリスクが生じます。
(例えば、プログラムのバグにより、存在しない'variation_id'を持つ画像が登録できてしまう、など)
もっといいデータの持ち方がある等
私は、'画像'と'商品共通の画像'は、別々のテーブルで表現する方が良い、と考えます。
具体的な方法は、
「'商品'は、必ず1つの'商品共通の画像'を持つ」
か否かによっても変わります。
'商品共通の画像'を持たない'商品'があり得るのであれば、
以下の図のように'商品共通の画像'('common_image' テーブル)を直接、'商品'テーブルに紐づけてやるのが良いでしょう。
(両テーブルの'id'カラムに外部キー制約を適用)
'商品'は必ず1つの'商品共通の画像'を持つのであれば、
いっそのこと'商品'と'商品共通の画像'を1つのテーブルに統合し、各カラムに NOT NULL 制約を課してしまう、という手もあります。
これなら、整合性の無いデータが登録されたり、データが欠落したりするのをDBのレイヤーで防ぐことができますので。
ちなみに、'バリエーション'テーブルの'id'カラムがプライマリキーであれば、'画像'テーブルの'id'カラムと'item_id'カラムは不要です。
'variation_id'カラムさえあれば各レコードの一意制を確保でき、'バリエーション'テーブルと1対1の紐付けも可能だからです。
(さらに言うと、'バリエーション'テーブルの'id'カラムがプライマリキーでなくとも、同様の理由により'画像'テーブルの'id'カラムは不要です。)
追記
共通画像とバリエーション画像のどちらも複数の画像を登録します
であれば、私の回答の
「'商品共通の画像'を持たない'商品'があり得る」
に若干の修正を加えるのが良さそうです。
具体的には、'商品共通の画像'テーブルに'item_id'カラムを追加し、
外部キー制約を
item.id <- common_image.item_id
という紐付けに変更します。
これなら、'商品共通の画像'も1つの商品につき複数、登録できます。
jawaさんの方法(中略)では不十分でしょうか?
「可能か不可能か?」
で言えば可能ではありますが、私はお勧めしません。
この方法は
「'商品共通の画像'は'商品'に属する('バリエーション'に属するわけではない)」
という、このデータモデルが持つ本来の関係性が崩れているからです。
関係性が崩れたテーブル設計は、予期しない別の問題を生む可能性があります。
現状は
バリエーションを結合させるときはvariation_idから0を除外する条件を付けるだけでいける
とお考えのようですが、今後、例えば
「商品ごとのバリエーションの数を表示したい」
となった場合、全てのCOUNT(*)
から -1 した値を表示しなければならなくなるなど、他のあらゆる場所で
「variation_id = 0 は特別」
であることを意識しなければならなくなります。
開発者が(今後もずっと)msx2 様お一人なら問題が生じる可能性は低いかもしれませんが、
複数人で開発していたり、担当が交代する可能性があるのであれば、この「意識」を全員が維持しつづけるのは意外に難しいものです。
投稿2016/08/24 03:19
編集2016/08/24 06:08総合スコア4791
0
今の方針でも問題ないように思います。
おそらくvalidation_id=-1という架空のバリエーションを使用することが気持ち悪いと感じているのではないでしょうか?
自分が設計するなら、例えばvalidation_id=0は共通設定用バリエーションとして使うものとし、全ての商品に対し必ず1件登録するバリエーションとしてしまいます。
そのうえで、商品⇒バリエーション(共通含む)⇒画像の親子関係を構成すると思います。
■商品情報(item)
item_id
item_name
item_price
■バリエーション情報(variation)
item_id
valietion_id
color
size
■画像(image)
item_id
variation_id
image_id
image_name
comment
■データ例
[item] item_id, item_name, item_price -------------------------------------- S01,商品1,100 S02,商品2,200 -------------------------------------- [variation] item_id, valietion_id, color, size -------------------------------------- S01, 0, NULL , NULL S01, 1, RED , 50 S01, 2, BLUE , 50 S02, 0, NULL , NULL S02, 1, BLACK, 80 -------------------------------------- [image] item_id, valietion_id, image_id, image_name, comment -------------------------------------- S01, 0, S01_0 , S01_PACKAGE , CMT1 S01, 1, S01_1_1, S01_RED_FRONT , CMT2 S01, 1, S01_1_2, S01_RED_SIDE , CMT3 S01, 2, S01_2_1, S01_BLUE_FRONT, CMT4 S01, 2, S01_2_2, S01_BLUE_SIDE , CMT5 S02, 0, S02_0 , S02_PACKAGE , CMT6 S02, 1, S02_1 , S02_BLACK , CMT7 --------------------------------------
投稿2016/08/23 11:50
総合スコア3013
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
多対多のリレーションについてリンク先のページはとても参考になりました。
おすすめ本はポチってしまいました。
お役に立ててよかったです!
例えば3色バリエーションの商品があるとして
赤、緑、黄色みたいなイメージですよね。
複数の商品で共通のバリエーションを使わないなら、variationにitem_idをもたせた方が良さそうですね。
共通のバリエーションを使いたいなら画像と同じように関連テーブルを用意した方が良いでしょう。
例えば
color -> red
size -> small
みたいなレコードを商品Aだけしか使わないなら、variationにitem_idを追加した方が良いです。
商品A、B、Cでも使うなら関連テーブルを用意した方が良いです。
投稿2016/08/23 09:27
総合スコア19
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/08/23 09:29
2016/08/24 00:46
0
itemがimage_id、variation_idを持つようにしたほうが自然なように思います。
これによって複数の商品が同じ画像を参照することができます。
■商品情報(item)
id
item_name
item_price
variation_id
image_id
■バリエーション情報(variation)
id
color
size
■画像(image)
id
image_name
comment
投稿2016/08/23 07:06
総合スコア19
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/08/23 07:16
2016/08/23 07:37 編集
2016/08/23 08:28
2016/08/23 11:52 編集
2016/08/24 00:43
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/08/24 04:12
2016/08/24 06:08
2016/08/24 06:35
2016/08/24 07:02