2016-04-24 37 views
0

我正在开发个人项目以了解Redis。我试图用它作为管理酒店的数据库。我正试图围绕如何管理预订。Redis建模保留

问题是,有多个房间,每个房间可以有多个预订,存储日期从和日期到。我只是不确定我能如何模拟这个模型,以便有效地找到给定时期的空房间。

目前,我一直在考虑为每个单独的房间保存预订,但是这样我就必须逐个遍历房间,直到找到合适的房间为止。

欢迎任何输入。谢谢

+0

做保留有最小固定时间长度吗?例如,任何保留必须至少有一天,从中午开始和结束? – aembke

+0

是的,这正是你描述它的方式。预订至少24小时,开始/结束于中午。另一方面,没有最大长度。 –

回答

1

一种方法是使用集合来表示一个日期范围,其中每个集合代表一天,并由一个整数标识。然后一套会员将代表当天哪些房间可供预订。由于预订在每天的同一时间开始和结束,并且可以在整天内测量任何预订,因此您可以将任意一天表示为整数。例如,使用Unix纪元(1970年1月1日)为开始时间,今天(2016年4月24日)将是16915.或者在JavaScript:

Math.floor(new Date().getTime()/(1000 * 60 * 60 * 24)); 

然后,您可以找到可用的会议室给定日期通过在输入范围内的日期间设置一个交集。 This gives you O(n * m) lookup time其中n是最小集合的大小,m是集合的数量。由于该集合最多包含每个房间,因此这意味着n以房间总数为界。例如:

var _ = require("lodash"); 

var dateToInt = function(date){ 
    return Math.floor(date.getTime()/(1000 * 60 * 60 * 24)); 
}; 

var roomsInRange = function(client, start, end, callback){ 
    client.sinter(_.range(dateToInt(start), dateToInt(end)), callback); 
}; 

当用户预约日期范围的房间时,您将从日期范围中的每个集合中删除该房间号码。

var _ = require("lodash"); 

var dateToInt = function(date){ 
    return Math.floor(date.getTime()/(1000 * 60 * 60 * 24)); 
}; 

var reserveRoom = function(client, start, end, room, callback){ 
    var trx = client.multi(); 
    _.each(_.range(dateToInt(start), dateToInt(end), function(day){ 
    trx.srem(day, room); 
    }); 
    trx.exec(callback); 
}; 

这种方法复制大量的数据,每个房间都代表多次,但大小是由房间的数量,你需要是最大的日期范围为界。例如,我不认为用户可以提前5年预订预订,也不允许过去预订预订,这意味着除了限制输入范围的上限之外,您还可以清理过去的条目。鉴于密钥是整数,房间也可能以整数表示,如果这一年的预订花费超过1或2 MB,我会感到惊讶。

+0

这是一个解决问题的非常有趣的方式,它应该适用于我正在做的事情。它也使用redis的强项。我不确定我是否理解最后一个例子中的异步行为。你能详细说明一下吗? –

+0

哎呀,我在使用redis事务之前从之前的编辑中找到了它。现在删除它。 – aembke

+0

清除它。您提供的解决方案非常清晰,思路清晰,给了我一个关于如何在使用redis时创造性思考的新视角及其功能集。感谢您花时间写下所有这些。 –