Схема БД, много-много или значение bool в таблице

89
7

Если у меня есть куча ресторанов в моем баре, и у каждого ресторана может быть меню обеда, меню ужина или меню бранча, имеет ли смысл иметь логические значения в таблице ресторанов так:

Ресторан id | Имя Restuarant | Адрес | и т.д. | Меню обеда | Меню обеда | Меню Бранч

Или мне нужно создать таблицу меню, а затем иметь таблицу RestaurantMenu (много-много отношений)

Идентификатор меню | Название меню

1 | обеденное меню

2 | Меню ужина

3 | бранч-меню

спросил(а) 2021-01-19T20:53:32+03:00 6 месяцев, 2 недели назад
1
Решение
64

Другое предложение состоит в том, что вы используете таблицу компоновщиков. Это было бы более удобным и легко документированным. Таблица компоновщиков используется, когда у вас есть отношения "многие ко многим". (В ресторане может быть много типов меню, и определенное меню можно использовать во многих ресторанах).

Это позволяет добавлять дополнительные типы меню в виде строки в таблицу "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 Lunch
McDonald Breakfast
McDonald Dinner
Moe Breakfast
Moe Lunch
Steak & Shrimp House Dinner

ответил(а) 2021-01-19T20:53:32+03:00 6 месяцев, 2 недели назад
45

Мое предложение состоит в том, чтобы использовать простой битмаксный тип поля:

Например:

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

Вы можете добавить больше, если это станет необходимым.

Если в ресторане есть как завтрак, так и обед, но не завтрак и обед, это 1 + 4, поэтому колонка получает 5.

Если в ресторане есть все вышеперечисленное, это 1 + 2 + 4 + 8, что составляет 15.

Однако он, вероятно, не самый читаемый для будущих поддерживающих db. Это, однако, простой способ иметь один столбец, указывающий несколько вариантов.


Редактировать:

Это просто бинарная манипуляция. Он работает следующим образом:

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 хранит достаточное количество бит.

В вашей программе вы можете определить, какие меню доступны с некоторыми побитовыми операторами. В С#, например:

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");

ответил(а) 2021-01-19T20:53:32+03:00 6 месяцев, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема