かすてらすねお。

見聞録的ななにか。

飲食店の「料理」と「セット料理」のテーブル設計方法

想定場面

「炭焼きレストランさわやか」の創業価格フェア時の「げんこつ倶楽部」(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まで。