餐馆网站的一对多关系?

时间:2010-03-31 22:55:50

标签: database data-modeling

每个餐厅都有餐厅分店,每个分店必须确定它开放的一周中的哪一天,每天必须确定(几个)open_hour和close_hour到那一天。

我使用这些表创建了一对多的关系: rest_names ---> rest_branches ---> open_days ---> OPEN_HOURS

我是这样走的吗?还是有另一种方法可以做到这一点,也许不那么复杂? 那个查询将如何在特定的日子里获得餐厅的营业时间,比如星期天?

6 个答案:

答案 0 :(得分:3)

我建议存储开放时间,然后存储每个餐厅保持开放的时间,而不是关闭时间。这样可以更容易地计算开放时间,并且还可以避免餐厅在午夜后保持开放的模糊性。

示例设计,使用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)

答案 1 :(得分:0)

这取决于您如何存储开放日期(我假设您使用的是日期值),但只要DBMS的数据类型支持日期和时间,您就可以将日期和时间组合在一个列中。这将消除必须将“open_hours”加入“open_days”。

答案 2 :(得分:0)

你走在正确的道路上。我看到的实体是:

  • 连锁餐厅(例如TGI Friday's)
  • 餐厅(特定一个);
  • 开放时间(餐厅,日,开放时间,关闭时间)

拥有一个实体是不必要的。

答案 3 :(得分:0)

一家餐馆为许多分店命名 许多分支到许多开放日
很多开放时间到很多开放时间

选择[columnnames]
来自open_days
在open_days.rest_branchId = rest_branches.rest_branchId上加入rest_branches 在rest_name.rest_nameId = rest_branch上加入rest_name open_days ='sunday'的地方

答案 4 :(得分:0)

从数据模型设计中,并不一定要将ID列作为链和分支表中的主键:您可能必须为其他列定义唯一约束(例如链名称,例如),该列可能完全是主键。 ID列将是代理键,您可以决定是否使用它。有些人认为总是拥有这样一个主键是一种好习惯,但并不是绝对必要的。您甚至可能会发现在许多情况下它不值得拥有它。

答案 5 :(得分:0)

您可以考虑将餐厅名称,星期几和营业时间放在一张桌子上 例如。 Freds Diner /周一/ 10.00 / 22.00 /周二/ 11.00 / 21.00 /等 在您发送规范化警察之前,请注意在此结构中保持完整的完整性。在可预见的未来,任何人都不太可能创造一周中的新的一天 关于是否使用此结构的考虑因素涉及以编程方式访问/读取/更新信息的容易程度。 如果需要,您还可以将餐厅地址包含在同一行中。 注意。 'Address'是属性类型 - 本身不是属性。它是一个COMPOSITE属性类型,就像DATE一样。 NAME +属性类型=属性EG INVOICE + ADDRESS =发票地址和INVOICE + DATE =发票日期。发票地址和发票日期都是单一复合属性,并遵循相同的规则。 关于数据结构的主要问题是数据完整性 - 规范化只是一种尝试确保数据完整性的方法。