Один-ко-многим на сайте ресторана? - PullRequest
1 голос
/ 01 апреля 2010

В каждом ресторане есть филиалы ресторана, каждый филиал должен определять, какие дни недели он открывает, каждый из этих дней должен определять (несколько) open_hour и close_hour через этот день.

Я создал отношения один ко многим, используя эти таблицы: rest_names ---> rest_branches ---> open_days ---> open_hours

Я пойду правильно? или есть другой способ сделать это, может быть, менее сложный? А как будет выглядеть запрос, чтобы узнать часы работы ресторана в определенный день, скажем, в воскресенье?

Ответы [ 6 ]

3 голосов
/ 01 апреля 2010

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

Пример оформления с использованием MySQL:

CREATE TABLE restaurant_chains (
    id int AUTO_INCREMENT PRIMARY KEY,
    name varchar(20)
);

CREATE TABLE restaurant_branches (
    id int AUTO_INCREMENT PRIMARY KEY,
    chain_id int NOT NULL,
    locality varchar(20)
);

CREATE TABLE opening_times (
    id int AUTO_INCREMENT PRIMARY KEY,
    branch_id int NOT NULL,
    day_of_week int NOT NULL,
    open_time time,
    open_duration time
);

Обязательно добавьте соответствующий внешний ключ и уникальные ограничения. Вы также можете добавить проверочное ограничение, чтобы day_of_week всегда находилось в диапазоне от 1 до 7, поскольку это будет представлять день недели (1 для воскресенья, 2 для понедельника и т. Д.).

Теперь давайте заполним нашу базу данных некоторыми тестовыми данными:

INSERT INTO restaurant_chains VALUES (NULL, 'Chain A');
INSERT INTO restaurant_chains VALUES (NULL, 'Chain B');

INSERT INTO restaurant_branches VALUES (NULL, 1, 'Branch 1 for A');
INSERT INTO restaurant_branches VALUES (NULL, 1, 'Branch 2 for A');
INSERT INTO restaurant_branches VALUES (NULL, 2, 'Branch 1 for B');
INSERT INTO restaurant_branches VALUES (NULL, 2, 'Branch 2 for B');

INSERT INTO opening_times VALUES (NULL, 1, 1, '10:00:00', '04:00:00');
INSERT INTO opening_times VALUES (NULL, 1, 1, '19:00:00', '03:00:00');
INSERT INTO opening_times VALUES (NULL, 1, 2, '08:00:00', '12:30:00');
INSERT INTO opening_times VALUES (NULL, 2, 1, '19:00:00', '05:15:00');
INSERT INTO opening_times VALUES (NULL, 2, 2, '19:00:00', '04:00:00');

Следующий запрос возвращает время открытия, время закрытия и продолжительность для всех ресторанов:

SELECT  rb.locality,
        ot.day_of_week,
        ot.open_time,
        ADDTIME(ot.open_time, open_duration) AS close_time,
        ot.open_duration
FROM    opening_times ot
JOIN    restaurant_branches rb ON (rb.id = ot.branch_id)
JOIN    restaurant_chains rc ON (rc.id = rb.chain_id);

+----------------+-------------+-----------+------------+---------------+
| locality       | day_of_week | open_time | close_time | open_duration |
+----------------+-------------+-----------+------------+---------------+
| Branch 1 for A |           1 | 10:00:00  | 14:00:00   | 04:00:00      | 
| Branch 1 for A |           1 | 19:00:00  | 22:00:00   | 03:00:00      | 
| Branch 1 for A |           2 | 08:00:00  | 20:30:00   | 12:30:00      | 
| Branch 2 for A |           1 | 19:00:00  | 24:15:00   | 05:15:00      | 
| Branch 2 for A |           2 | 19:00:00  | 23:00:00   | 04:00:00      | 
+----------------+-------------+-----------+------------+---------------+
5 rows in set (0.00 sec)

Тогда следующий запрос вернет часы работы определенного ресторана в определенный день:

SELECT  ot.open_time,
        DATEADD(ot.open_time, open_duration) AS close_time,
        ot.open_duration
FROM    opening_times ot
JOIN    restaurant_branches rb ON (rb.id = ot.branch_id)
JOIN    restaurant_chains rc ON (rc.id = rb.chain_id)
WHERE   rb.id = 1 AND ot.day_of_week = 1;

+-----------+------------+---------------+
| open_time | close_time | open_duration |
+-----------+------------+---------------+
| 10:00:00  | 14:00:00   | 04:00:00      | 
| 19:00:00  | 22:00:00   | 02:00:00      | 
+-----------+------------+---------------+
2 rows in set (0.00 sec)
0 голосов
/ 28 мая 2010

Вы можете рассмотреть название ресторана, день недели и часы работы на одном столе.
НАПРИМЕР. Freds Diner / понедельник / 10.00 / 22.00 / вторник / 11.00 / 21.00 / и т. Д. И прежде чем отправлять полицию нормализации, обратите внимание, что в этой структуре поддерживается полная целостность. Вряд ли кто-то собирается создать новый день недели в обозримом будущем.
Соображения относительно того, следует ли использовать эту структуру, относятся к тому, насколько просто программно получить доступ / прочитать / обновить информацию. Вы также можете указать адрес ресторана в той же строке, если это необходимо. Заметка. «Адрес» - это тип атрибута, а не атрибут как таковой. Это тип атрибута COMPOSITE, как и DATE. ИМЯ + Тип атрибута = Атрибут EG СЧЕТ + АДРЕС = Адрес счета и СЧЕТ + ДАТА = Дата счета. Адрес счета-фактуры и Дата счета-фактуры являются отдельными составными атрибутами и следуют одним и тем же правилам. Основной проблемой, касающейся структуры данных, является целостность данных. Нормализация - это просто способ попытаться обеспечить целостность данных.

0 голосов
/ 01 апреля 2010

При проектировании модели данных не обязательно иметь столбец идентификатора в качестве первичного ключа в таблицах для цепочек и ветвей: вам может потребоваться определить уникальное ограничение для некоторого другого столбца (например, для имени цепочкинапример), и этот столбец может быть первичным ключом.Столбец ID будет суррогатным ключом, и вы можете решить, иметь его или нет.Некоторые люди считают хорошей практикой всегда иметь такой первичный ключ, но это не является строго необходимым.Вы можете даже обнаружить, что во многих случаях это не стоит иметь это.

0 голосов
/ 01 апреля 2010

названия одного ресторана во многих филиалах
много веток ко многим дням открытых дверей
много открытых дней ко многим открытым часам

выберите [имена столбцов]
от open_days
присоединиться к rest_branches на open_days.rest_branchId = rest_branches.rest_branchId
присоединиться к rest_name на rest_name.rest_nameId = rest_branch
где open_days = 'воскресенье'

0 голосов
/ 01 апреля 2010

Вы на правильном пути. Сущности, которые я вижу:

  • Сеть ресторанов (например, TGI Friday's)
  • Ресторан (конкретный);
  • Время открытия (ресторан, день, время работы, время закрытия)

Наличие сущности на день кажется ненужным.

0 голосов
/ 01 апреля 2010

Это зависит от того, как вы храните дни открытых дверей (я полагаю, вы используете значение даты), но вы можете объединить дату и время в одном столбце, если это поддерживает тип данных для СУБД. Это исключило бы необходимость присоединения open_hours к open_days.

...