我需要设计一个数据库来管理具有多个体育中心的系统中的安装预约。这些中心有不同的设施,如游泳池,网球场,篮球场等。在一个中心可能有不止一个游泳池或网球场等。他们可以有不同的可用性。例如,“中心1”中的“游泳池1”和“游泳池2”可在周一,周三和周五的9:00至10:00和12:00至13:00使用。 “游泳池2”也可在周二和周四的08:00至09:00和09:00至10:00使用。我还可以添加排除日期(如假期),例如2015年12月25日星期五和2016年1月1日星期五。然后,如果仍然可以,会员可以预订和安装。
现在我有以下表格:
CENTER
Id | Name
----|-----------
1 | Center 1
2 | Center 2
3 | Center 3
INSTALLATION TYPE
Id | Description
----|----------------
1 | Swimming
2 | Tennis
3 | Basketball
INSTALLATION
Id_center | Id_installation | Name | Id_type
------------|-------------------|-------------------|-----------
1 | 1 | Swimming pool 1 | 1
1 | 2 | Swimming pool 2 | 1
2 | 1 | Tennis court 1 | 2
MEMBER
Id_center | Id_member | Name
------------|---------------|-------------
1 | 1 | John Doe
2 | 1 | Sarah Bole
我正在考虑以下几点:
SCHEDULE
Id_center | Id_installation | Day_week | Time_begin | Time_end
------------|-------------------|---------------|---------------|------------
1 | 1 | 1 | 09:00 | 10:00
1 | 1 | 1 | 12:00 | 13:00
1 | 2 | 1 | 09:00 | 10:00
1 | 2 | 1 | 12:00 | 13:00
1 | 2 | 2 | 08:00 | 09:00
1 | 2 | 2 | 09:00 | 10:00
EXCLUDING DAYS
Id_center | Id_installation | Date
------------|-------------------|-------------
1 | 1 | 06/10/2015
1 | 1 | 12/25/2015
1 | 2 | 12/25/2015
RESERVATION
Id_center | Id_installation | Id_member | Date | Time_begin | Time_end
------------|-------------------|---------------|---------------|---------------|------------
1 | 2 | 2 | 05/28/2015 | 08:00 | 09:00
1 | 2 | 2 | 05/28/2015 | 09:00 | 10:00
1 | 1 | 1 | 05/25/2015 | 09:00 | 10:00
你会添加或修改什么?
感谢。
答案 0 :(得分:1)
匆匆一瞥,你似乎在一小时的街区内发出预订。如果是这样,请考虑取消使用Time_End列。
这是一个想法:
create table Reservations(
CenterID...,
InstallationID...,
MemberID ...,
Date ...,
Time_Begin ...
);
例如,如果您提前六个月进行预订,则可以为每个可用日期输入一个条目,因为它超过了六个月的阈值。它具有日期,该日期可用的最早小时(来自Schedule表)和null
的MemberID。 null
表示它可用。由于没有其他条目,因此可以在一整天内使用。当会员进行预订时,插入该时间的记录或更新当时的null
记录,并在预订结束时插入另一条null
记录 - 如果还没有预约那个时候。
喜欢这个。这是每个新的一天开始的方式:
Center Install Member StartTime
====== ======= ====== ================
1 1 null 05/28/2015 08:00
会员14从早上8点开始预约一小时。
Center Install Member StartTime
====== ======= ====== ================
1 1 14 05/28/2015 08:00
1 1 null 05/28/2015 09:00
会员27在中午预约一小时:
Center Install Member StartTime
====== ======= ====== ================
1 1 14 05/28/2015 08:00
1 1 null 05/28/2015 09:00
1 1 27 05/28/2015 12:00
1 1 null 05/28/2015 13:00
这表示会员1从08-09开始预订,从09-12开始预订,会员27预订12-13,可从13日开始预订。
当成员42想要保留11am插槽时,只需要一个插入作为该插槽的末尾,中午已经有记录。
Center Install Member StartTime
====== ======= ====== ================
1 1 14 05/28/2015 08:00
1 1 null 05/28/2015 09:00
1 1 42 05/28/2015 11:00
1 1 27 05/28/2015 12:00
1 1 null 05/28/2015 13:00
这可以这样解读:
select r.*, r1.StartTime as EndTime
from Reservations r
left join Reservations r1
on r1.Center = r.Center
and r1.Install = r.Install
and r1.StartTime =(
select Min( StartTime )
from Installation
where Center = r.Center
and Install = r.Install
and trunc( StartTime ) = trunc( r.StartTime )
and StartTime > r1.StartTime )
where r.Center = :Center
and r.Install = :Install
and r.StartTime between :DayOfInterest and :DayOfInterest + 1;
显示特定日期的所有条目。 Member
为空时,时间可用。如果EndTime
为空,则该预留或可用性将在计划日期结束时进行。所以只需添加到过滤器:
and r.Member is [not] null
仅显示可用性或仅显示预订。
乍一看,查询可能看起来有点吓人,但它遵循一致的模式来阅读版本化的表。