如果我的数据库中有很多餐厅,每个餐厅都可以有午餐菜单、晚餐菜单或早午餐菜单,那么在restaurants表中设置布尔值有意义吗
餐厅id |餐厅名称|地址|等|午餐菜单|晚餐菜单|早午餐菜单
或者我应该创建一个菜单表,然后有一个RestaurantMenu表(多-多关系)
菜单id |菜单名称
1|午餐菜单
2|晚餐菜单
3|早午餐菜单
另一个建议是使用链接器表。这将更易于维护和记录。当您具有多对多关系时,会使用链接器表。(一家餐厅可以有许多类型的菜单,许多餐厅都可以使用特定类型的菜单。)
这使您可以稍后在"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
我的建议是使用一个简单的位掩码类型的字段:
例如:
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");