2012-03-19 17 views
0

如果我在我的分貝中有一堆餐館,並且每個餐館都可以有午餐菜單,晚餐菜單或早午餐菜單,是否有意義使用布爾值在餐廳表中,如下所示:數據庫架構,表中的許多或bool值

餐廳ID |餐館名稱|地址|等午餐菜單|晚餐菜單|早午餐菜單

或者我應該創建一個菜單表,然後有一個RestaurantMenu表(多對多關係)

菜單ID |菜單名稱

1 |午餐菜單

2 |晚餐菜單

3 |早午餐菜單

+0

如果只有3個具有'bool'類型的菜單欄,那麼不需要創建另一個表 – safarov 2012-03-19 20:34:24

+0

因此,一間餐廳可以有多個菜單,還是僅限於其中一種? – 2012-03-19 20:37:29

+0

老實說,這個問題的答案取決於您是否認爲需要將其他菜單類型添加到數據庫中。如果你確定你已經覆蓋了所有類型,那麼使用'bool'列將非常容易使用和查詢。但如果你不得不增加一個,這可能是一個頭痛的問題。我提供了兩個答案,展示了我用於擴展的幾種方法。 – JYelton 2012-03-19 20:58:12

回答

1

另一個建議是您使用鏈接器表。這將更易於維護和記錄。當您有多對多關係時使用鏈接表。 (一家餐館可以有多種類型的菜單,許多餐館都可以使用特定類型的菜單。)

這可以讓您在稍後的「menu_types」表格中將其他菜單類型添加爲行,而無需更改結構的任何表格。

它確實使您的查詢更加複雜,但是,因爲您必須執行一些連接。

首先,你將有三個表是這樣的:

restaurants 
--------------- 
id name 
1  Moe's 
2  Steak & Shrimp House 
3  McDonald's 

restaurant_menus 
---------------- 
restaurant_id menu_type 
1    1 
1    3 
2    4 
3    1 
3    3 
3    4 

menu_types 
--------------- 
id type 
1  Breakfast 
2  Brunch 
3  Lunch 
4  Dinner 

所以,看到什麼樣的菜單每家餐廳的優惠,您的查詢是這樣的:

SELECT r.name, mt.type 
FROM restaurants r 
    JOIN restaurant_menus rm 
     ON (r.id = rm.restaurant_id) 
    JOIN menu_types mt 
     ON (rm.menu_type = mt.id) 
ORDER BY r.name ASC; 

這將產生:

name     type  
-------------------- ----------- 
McDonald's   Lunch  
McDonald's   Breakfast 
McDonald's   Dinner  
Moe's     Breakfast 
Moe's     Lunch  
Steak & Shrimp House Dinner  
+0

嗨,謝謝你的真棒回答。現在我正在爲一個iphone-app實現這個功能,而且我正在使用HTTP GET。以下是我正在使用的SQL查詢,但它不包含連接。這是否足夠有效? 「SELECT菜單名稱從菜單其中menu_id IN(SELECT menus_id FROM Restaurants_Menus WHERE Restaurants_id ='$ restaurantID')」 – Apollo 2012-03-19 21:34:48

+0

我想說這是一個關於SQL查詢效率的新問題。但總的來說,以我的經驗來看,子查詢的效率並不高。這取決於您對索引和其他因素的實施。 – JYelton 2012-03-20 14:49:02

+0

好的謝謝你的建議 – Apollo 2012-03-20 15:59:43

0

我的建議是使用現場的簡單位掩碼類型:

例如:

1 = breakfast 
2 = brunch 
4 = lunch 
8 = dinner 

您可以添加更多,如果有必要。

如果餐廳提供早餐和午餐,但不早午餐也不吃晚飯,這就是1 + 4,因此列得5

如果餐廳有以上所有的,這就是1 + 2 + 4 + 8 ,這是15.

但是,它可能不是未來數據庫維護者最可讀的。但是,一個簡單的方法可以讓一列顯示多個選項。

編輯:

這僅僅是簡單的二進制操作。它的工作原理是這樣的:

Dinner Lunch Brunch Breakfast 
-------- ------- -------- --------- 
0  0  0  1    1 (Breakfast only) 
1  1  0  0    12 (Dinner + Lunch) 
1  1  1  1    15 (All four) 

這種場的好處是,你可以添加額外的菜單類型,而無需更改數據庫,假設你的INT字段存儲足夠的位。

在您的程序中,您可以確定某些按位運算符可用的菜單類型。在C#中,例如:

const int BREAKFAST = 1; 
const int BRUNCH = 2; 
const int LUNCH = 4; 
const int DINNER = 8; 

int RestaurantMenuType = 5; 

bool OffsersBreakfastMenu = (RestaurantMenuType & BREAKFAST) == BREAKFAST; 
bool OffsersBrunchMenu = (RestaurantMenuType & BRUNCH) == BRUNCH; 
bool OffsersLunchMenu = (RestaurantMenuType & LUNCH) == LUNCH; 
bool OffersDinnerMenu = (RestaurantMenuType & DINNER) == DINNER; 

Console.WriteLine("Offers breakfast? {0}", OffsersBreakfastMenu ? "Yes" : "No"); 
Console.WriteLine("Offers brunch? {0}", OffsersBrunchMenu ? "Yes" : "No"); 
Console.WriteLine("Offers lunch? {0}", OffsersLunchMenu ? "Yes" : "No"); 
Console.WriteLine("Offers dinner? {0}", OffersDinnerMenu ? "Yes" : "No"); 
+1

但是如果你有'4',你會如何區分'3 + 1'?我認爲你的意思是'2^X',對吧? – 2012-03-19 20:36:03

+0

BUt比1 + 3 = 4和4也是晚餐。所以你需要0 - 沒有菜單,1 - 早餐,2 - 早午餐,4 - 午餐,8 - 晚餐(2^n) – safarov 2012-03-19 20:38:36

+0

我開始使用二進制的虛假應用程序,並自此編輯了答案。我對此表示歉意,我沒有正確地轉換事情。值應該是1,2,4,8等等,而不是1,2,3,4等。 – JYelton 2012-03-19 20:56:27