酒店预订系统设计 - 使用多个房间的预订

时间:2012-03-10 15:31:33

标签: .net sql database-design

我在预订系统等酒店房间寻找一些设计建议。 到目前为止,我已经阅读了很多这方面的内容,并且我有一个查询返回一个可用于特定日期范围的房间列表。

我的搜索目前仅返回用户正在搜索的整个预订期间可用的房间。我想扩展这个,以便我可以满足多个房间的要求。即用户搜索日期范围,前2天可以使用房间1,然后在过去2天内需要将它们转移到2号房间。

我目前使用以下查询进行可用性查找;

Dim available = From k In rooms _
            Group Join r In db.Reservations.Where(Function(fx) (fx.DateIn >= Date_From And fx.DateIn < Date_To) Or (fx.DateOut > Date_From And fx.DateOut <= Date_To)) On k Equals r.Room Into Group _
            From r In Group.DefaultIfEmpty
            Where r Is Nothing
            Select k

如何更改我的设计或扩展当前设计以允许每次预订多个房间?我有点难过!

提前致谢!

3 个答案:

答案 0 :(得分:1)

如果您将初始查询更改为仅搜索人员到达日期可用的房间,并按每个房间按降序排列的最长时间排序,该怎么办?如果这段时间足以支付这个人的住宿,那么你就完成了。如果不是,请递归。再次查询以搜索第一个房间不可用日期可用的房间,再次按每个房间按降序打开的最长时间排序。继续,直到你找到一个没有空房的日期,或者你已经找到足够的房间来支付这个人的住宿。

例如,假设您有人想要从1/1 - 1/10预订预订,并且有三个房间具有以下可用性:

  • 房间1:可从1/1到1/9
  • 房间2:1/1至1/5
  • 房间3:1/5至1/10

您的第一个查询是查看1/1的哪些房间可用,这将返回房间1和2.但是,由于您按照每个房间开放的最长时间排序,您的最高结果将是房间1.您的第二个问题是查看哪些房间在1/10(第一个日期房间1变得不可用)可用,这将返回房间3.然后您将确定房间3打开足够长的时间以满足人的预订,你已经完成了。

答案 1 :(得分:0)

好的,在SQL中:

表room_booking与roomid INT (FK to room table), from DATE, to DATE

类似

如此决定如果有足够的空间将是相反的问题:在访问的时间范围内,是否存在没有房间可用的情况?所以我们在几天之内拆分框架(因为在你的情况下,房间不按小时租用,或者是吗?)并选择它。

因此,您需要在选择之前确定每天的访问时间,然后计算每天有多少免费房间。

然后这个:

SELECT count(roomid) - (SELECT count(id) from room) as numOfFreeRooms
FROM room_booking
WHERE '2012-03-10' >= from AND '2010-03-10' <= to

如果任何行返回'0'(表示当天预订所有房间),那么您无法满足客户的要求。

如果表现相关,那么这可以改善,但更复杂。

答案 2 :(得分:0)

所以我的第二个解决方案,它(如第一个评论中所述)相当复杂,但我认为它非常有效。

我不会发布代码而是发布整体概念,如果您对具体细节感兴趣,我会看到我能做些什么。

问题:我们创建了一个抽象,每天的每个房间都可用或被阻止。我们对客人想要访问的房间感兴趣。 我们希望选择需要最少重新定位客房的房间组合。

摘要:我们创建了一个房间/日组合的二维矩阵,其中每天由2的幂(DAYVALUE)表示。可用的房间有相应的DAYVALUE。一个房间被封锁为SERO的价值。因此,如果我们将所有DAYS总和为ROOM,我们就可以确定ROOMS的组合能够满足全部时间。

更具体:在我们获得ROOM的所有VALUES的SUM之后,我们可以使用二元OR函数通过比较OR运算的结果和值的SUM来确定给定的房间组合是否满足整个停留时间。所有的日子。

请注意,DAYVALUE未存储在dayTable中。它是针对每个请求计算的(2 ^(STARTDAY-DAY))

混凝土:

1)您需要创建一个包含所有DAYS的表。它只有一列包含一个日期(没有时间,没有时区只有一天)。我建议它包含从现在到一百年的所有日子。 (所以你只需要填充一次)。 (注意:这解决了您无法在SQL查询中每天选择一次的问题)

2)您创建一个VIEW,生成如下输出:

DAY      ; DAYVALUE ; ROOM1 ; ROOM2; ROOM3 ; ROOM4 ; ... ; ROOMn
20120313 ;        1 ;     0 ;     0;     1 ;     1 ; ... ;
20120314 ;        2 ;     2 ;     0;     2 ;     2 ; ... ;
20120315 ;        4 ;     4 ;     0;     0 ;     4 ; ... ;
20120316 ;        8 ;     8 ;     0;     0 ;     0 ; ... ;
20120317 ;       16 ;    16 ;    16;    16 ;     0 ; ... ;

3)产生一个SUM。

DAYVALUE ; ROOM1 ; ROOM2; ROOM3 ; ROOM4 ; ... ; ROOMn
      31 ;    30 ;    16;    19 ;     7 ; ... ;

4)看看是否有任何一个房间价值与DAYVALUE的总和相匹配(因此一直可用)

5)如果4没有成功,则每两个结果创建一个OR值,并将其与DAYVALUE的SUM进行比较

ROOM1 OR ROOM2 = 30 <> 31
ROOM1 OR ROOM3 = 31 == 31. This is a valid match of rooms.

6)如果两个房间没有匹配,则必须为3个房间进行此操作,依此类推。

使用此过程始终会生成访问时可用的正确房间集,如果以正确的方式构建数据库(或房间的数量足够少),查询应在可接受的时间内完成。

玩得开心(我有!)