hit*_*esh 5 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
Run Code Online (Sandbox Code Playgroud)
现在我的问题是,是否建议预先填充插槽,然后根据可用性为用户预订.但是在这种情况下对于abobe示例如果我需要在接下来的1个月内存储插槽,那么我将不得不提前存储11x18x30 = 5940条记录而没有任何真正的预订.每个午夜我都需要运行脚本来创建插槽.如果俱乐部没有增加,这个数字会变得很大.
是.这是一种可怕的方法.由于您所说的原因,还有更多.
存储非事实是荒谬的
大量非事实的存储是不合理的
如果需要编写简单的代码是一个问题,那就要正确处理,提高编码技巧,这样就不会出现问题(而不是将数据库降级为原始文件系统,以满足您的编码技能) .
请注意,您建议的是每个法院的日历(作为可视化或结果集不是不合理的),其中大多数插槽将为空(可用).
这种系统的优秀设计是什么?
不,这太可怕了.
它不是一种设计.这是一个没有设计的实现.
如果没有,那么这些场景中更好的设计是什么.
我们使用数据库.鉴于其无与伦比的地位,以及您的平台,特别是关系数据库.
我们只存储您需要的事实,关于您需要参与的现实世界.我们需要远离可视化我们必须完成的工作(数千个日历,部分为空),并将数据视为数据,并将其视为数据.包括所有规则和约束.
在此之后,事实的确定或事实的缺失很容易.我可以为您提供所需的关系数据库,但您必须能够编写SQL代码,以便有效地使用数据库.
试试这个:
这是一个IDEF1X数据模型.IDEF1X是关系数据库建模的标准.请注意每一个小嘀嗒声; 缺口; 并标记; 乌鸦脚; 实线与虚线; 广场与圆角; 意味着非常具体和重要的东西.请参阅IDEF1X表示法.如果您不理解符号,您将无法理解或使用该模型.
我包括:
仅存储事实(保留).事实(可用性)的事实或缺失很容易确定.
club_resource_slot.duration 在钥匙中允许任何持续时间,而不是假设一小时,这可能会改变.在任何情况下都需要它,因为它划分了时隙.
resource_code,而不是法院号码.这允许任何俱乐部的资源(以及法院号)被保留,而不是只有一个羽毛球或壁球场.您将来可能会有会议室.
rate在回答这个具体问题方面,Joel的答复非常正确.我在模型的其余部分的上下文中给出了一个更简单的形式(更少规范化,更容易编码).
如果您想要Predicates,请询问.
您似乎在编码的某些方面存在问题,我将首先解释:
但是这种方法的问题是,如果我需要根据游戏,位置,日期和时间段找到法院的可用性,那么我将不得不为所有俱乐部加载这个费率表,并且如果有人已经已经查看实际预订表预订了插槽.是不是更好的方法是如果我提前保留插槽然后有人预订,jst将状态更改为预订.所以该查询将完全在DB中执行,而不在内存中进行任何计算.
rate表的存在与否,不会产生问题.这可以通过连接来完成.描述的步骤不是必需的.
请注意,您当然不需要"加载整个表",但您可能需要加载一个表或其他表以填充下拉列表等.
当有人预订法庭时,只需插入预约VALUES()
当有人取消预订时,只需删除预订VALUES()
打印预留插槽矩阵应该很明显,很简单.
打印可用或可用加保留(您的日历视觉)矩阵需要投影.如果您不理解这种技术,请阅读本答案.一旦你理解了,代码就像[1]一样简单.
您需要能够编写子查询和派生表的代码.
确定插槽是保留还是可用需要简单查询.我将提供一些示例代码来帮助您."游戏"未指定,我将假设位置意味着俱乐部.
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"
Run Code Online (Sandbox Code Playgroud)请随时发表评论或提问.
从数据维护的角度来看,拥有一个包含法院的表(每个法庭 1 条记录)和一个包含预订的表(每个预订 1 条记录)可能会更有效。
该BOOKING记录应具有COURT预订开始日期/时间和预订结束日期/时间的外键。它还包含有关谁进行预订的信息,这可能是餐桌的外键CUSTOMER,也可能是填写的姓名等,具体取决于您的业务运作方式。
| 归档时间: |
|
| 查看次数: |
6668 次 |
| 最近记录: |