时隙数据库设计

时间:2015-04-25 17:41:06

标签: mysql database database-design

我正在创建一个数据库,需要允许在特定日期从开始时间到结束时间预订资源。例如,我有11个羽毛球场。这些法院可以预订1小时,也可以在一天内每天从早上6点到晚上12点进行18次预订。 (考虑每次预订是一小时)。预订价格也每天都有所不同,例如早上的费用超过了日费。周末费用超过工作日收费。

现在我的问题是,是否建议预先填充插槽,然后根据可用性为用户预订。但是在这种情况下对于abobe示例如果我需要在接下来的1个月内存储插槽,那么我将不得不提前存储11 * 18 * 30 = 5940条记录而没有任何实际预订。每个午夜我都需要运行脚本来创建插槽。如果俱乐部没有增加,这个数字会变得很大。这种系统的优秀设计是什么?如果没有,那么这些场景中的设计更好。

club name||court || date || start_time || end_time || status || charge ||

a           c1    20/04/2015   6:00        7:00       available
a           c1    20/04/2015   7:00        8:00       available
.
.
.
a           c1    20/04/2015   11:00       24:00      available

.
.
a           c11   20/04/2015   11:00       24:00      available

3 个答案:

答案 0 :(得分:7)

  

现在我的问题是,是否建议预先填充插槽,然后根据可用性为用户预订。但是在这种情况下对于abobe示例如果我需要在接下来的1个月内存储插槽,那么我将不得不提前存储11x18x30 = 5940条记录而没有任何实际预订。每个午夜我都需要运行脚本来创建插槽。如果俱乐部没有增加,这个数字就会变得很大。

是。这是一种可怕的方法。由于您所说的原因,还有更多。

  • 存储非事实是荒谬的

  • 大量非事实的存储是不合理的

  • 如果需要编写简单的代码是一个问题,请正确处理,提高编码技巧,这样就不会出现问题(而不是将数据库降级为原始文件系统,为了满足你的编码技巧)。

请注意,您建议的是每个法院的日历(这不是不合理的作为可视化,或作为结果集),其中大多数插槽将为空(可用)

  

这种系统的优秀设计是什么?

不,这太可怕了。

这不是设计。这是一个没有设计的实现。

  

如果没有,那么这些场景中的设计更好。

我们使用数据库。鉴于其无与伦比的地位,以及您的平台,特别是关系数据库。

我们只会存储您需要的事实,以及您需要参与的真实世界。我们需要远离可视化我们必须完成的工作(数千个日历,部分为空),并将数据视为数据,并将其视为数据。包括所有规则和约束。

在此之后,事实的确定或事实的缺失很容易。我可以为您提供您需要的关系数据库,但您必须能够编写SQL代码,以便有效地使用数据库。

数据模型

试试这个:

Resource Reservation Data Model

这是一个IDEF1X数据模型。 IDEF1X是关系数据库建模的标准。请注意每一个小嘀嗒声;缺口;并标记;乌鸦脚;实线与虚线;广场与圆角;意味着非常具体和重要的东西。请参阅IDEF1X Notation。如果您不理解符号,您将无法理解或工作模型。

我已经包括:

  • 仅存储事实(保留)。事实(可用性)的事实或缺失很容易确定。

  • 密钥中的
  • club_resource_slot.duration 允许任何持续时间,而不是假设一小时,这可能会改变。在任何情况下都需要它,因为它划分了时间段。

  • resource_code,而不是法院号码。这允许保留任何俱乐部资源(以及球场号码),而不是羽毛球或壁球场。您将来可能会有会议室。

  • Joel的回复rate表在回答该特定问题时非常正确。我在模型的其余部分的上下文中给出了一个更简单的形式(更少规范化,更容易编码)。

如果您想要Predicates,请询问。

代码/一般

您似乎在编码的某些方面存在问题,我将首先讨论这些问题:

  

但这种方法的问题是,如果我需要根据游戏,位置,日期和时间段找到法院的可用性,那么我将不得不为所有俱乐部加载此费率表并查看实际情况预订表,如果有人已经预订了插槽。是不是更好的方法是如果我提前保留插槽然后有人预订,jst将状态更改为预订。所以该查询将完全在DB中执行,而不在内存中进行任何计算。

  • rate表的存在与否,不会产生问题。这可以通过连接来完成。所描述的步骤不是必需的。

  • 请注意,您无需加载整个表格"当然,但您可能需要加载一个表或其他表来填充您的下拉菜单等。

  • 当有人预定法庭时,只需插入预约VALUES()

  • 即可
  • 当有人取消预订时,只需删除预订VALUES()

代码/数据模型

  1. 打印保留广告位的矩阵应该很明显,很简单。

  2. 打印可用或可用加保留(您的日历视觉)矩阵需要投影。如果您不理解这种技巧,请阅读this Answer。一旦你理解了,代码就像[1]一样简单。

  3. 您需要能够对子查询和派生表进行编码。

  4. 确定插槽是保留还是可用需要简单查询。我将提供一些示例代码来帮助您。 "游戏"没有指定,我将假设位置意味着俱乐部。

    IF (
        SELECT COUNT(*)                -- resources/courts reserved
            FROM reservation
            WHERE club_code = $club_code
            AND   date_time = $date_time
        ) = 0
    THEN PRINT "All courts available"
    ELSE IF (
            SELECT COUNT(*)            -- resources/courts that exist
                FROM club_resource_slot
                WHERE club_code = $club_code
                AND   date_time = $date_time
            ) = (
            SELECT COUNT(*)            -- resources/courts reserved
                FROM reservation
                WHERE club_code = $club_code
                AND   date_time = $date_time
            )
        THEN PRINT "All courts reserved"
        ELSE PRINT "Some courts available"
    
  5. 请随时发表评论或提问。

答案 1 :(得分:0)

从数据维护的角度来看,提供一个有法院的表格(每个法院有1个记录)和一个有预订的表格(每个预订1个记录)可能更有效率。

BOOKING记录应该有COURT预订开始日期/时间和预订结束日期/时间的外键。它还可以提供有关预订人员的信息,这可能是CUSTOMER表的外键,也可能是填写名称等,具体取决于您的业务运作方式。

答案 2 :(得分:0)

假设每次预订都是一小时(也就是说,如果有人想在法庭上花两个小时,他们每次需要两个小时的预订),在我看来,最有效的存储机制就是一张桌子{{ 1}}列BookingCourtDate(以及预订人员,付款说明等的其他列。)每次法院审核时,您都会插入一条记录预订了一个小时。

这个表格将是人口稀少的,因为只有预订的每小时单位的记录,而不是可用的单位。不会预先生成数据;你只会在预订时创建记录。

要生成每日或每周日历,您的应用程序将从数据库中检索预订的小时数,并将其与您的工作时间(早上6点至午夜)相关联,以生成法庭可用性的可视化。