想定場面
「炭焼きレストランさわやか」の創業価格フェア時の「げんこつ倶楽部」(999円)のメニュー構成は、
●「げんこつハンバーグ」(924円)
●「ライスまたはパン」(210円)
●「スープ」(210円)
●「ドリンク」(105円)
である。
「げんこつ倶楽部」とそれを構成する単品メニューの、
●メニュー番号 ●名前 ●価格
をデータベースに格納する時、どのようなテーブル設計が望ましいか。
[set_menu]*―1[menu] → [set_menu]―[set_content]―[menu]
table:[set_menu] int set_menu_id(Primary Key) | varchar(128) name | decimal value table:[menu] int menu_id(Primary Key) | varchar(128) name | decimal value
まず、メニューにもセットメニューにも●メニュー番号●名前●価格が存在するから、メニューとセットメニューというテーブルにそれぞれid, name, valueの項目があればいいだろ、と思った。
次に、セットメニューは複数のメニューを持っていることが分かるので、[set_menu]1―*[menu] と表現できる。このリレーションの情報は[set_menu]と[menu]の間にセットメニューを構成するメニューを表現する[set_content]というテーブルを設けることで表現できる。
table:[set_content] int set_menu_id(Foreign Key) | int menu_id(Foreign Key)
たとえば、げんこつ倶楽部はげんこつハンバーグとパンorライスとスープとドリンクを持っているわけだから、げんこつ倶楽部=SM01、げんこつハンバーグ=M001、パン=M002、ライス=M003、スープ=M004、コーラ=M005 というメニュー番号としたとき、
SM01 | M001 SM01 | M002 SM01 | M004 SM01 | M005
というデータを格納することになる。げんこつ倶楽部が何のメニューで構成されているかを知る時は、げんこつ倶楽部のメニュー番号=SM01が含まれるレコードを取り出せばいい。
[set_menu]を[menu]に吸収させる
しかし、セットメニューはメニューの一部です。別々のテーブルに分けていると、データの検索が少し面倒です。そこで、セットメニューをメニューと同じとみなして、以下のようなテーブルを設計します。
table:[menu] int menu_id(Primary Key) | varchar(128) name | decimal value table:[set_content] int menu_id(Foreign Key) | int menu_id(Foreign Key)
違いは、[set_menu]が消えたことと、set_contentの項目が両方ともmenu_idに
なったことです。こうすることで、メニューのテーブルをひとつにできます。
間違いや問題点などありましたら、@suneo3476Proまで。