用例:酒店客房的可用日历。
常规方法:
有一个列可用性表:(int)hotel_id,(date)date,(boolean)available
这意味着每个酒店按日期编制365行(如果我们考虑一年的可用性)
我想尝试的事情:
有一个列可用性表:(int)hotel_id,(bigint?)availability
每个酒店1行,使用按位运算符查询/更新可用性:
SELECT * FROM table WHERE (availability & mask) = mask
问题:
性能方面是值得的吗?
答案 0 :(得分:1)
除非你到达> 10 ^ 7行,你的数据库引擎应该做得很好,所以考虑到你的数字,你建议的常规方法没有错。即使您何时以及何时到达那里,更强大的服务器(向上扩展)和良好的DBA可以帮助您进一步扩展。
事实上,您建议的替代方案更糟糕 - 您可能无法正确索引可用性列,这意味着按日期查询将非常缓慢!
例如,您可能希望运行如下查询:SELECT hotel_id FROM hotel_avail WHERE avaliable = TRUE AND avail_date ='2011-04-01';您需要在日期列上使用索引才能快速运行。
最重要的是,滚动自己的可用性和掩码方案会增加系统的复杂性。理解和维护代码可以更加难以理解“可用性魔法”。相信我,我一直在那里 - 它最初可能看起来很漂亮,但过了一段时间你就不记得自己这些技巧是如何工作的,它会成为一场噩梦。
最后,就像@ mark-tozzi所提到的那样,过早优化是一个坏主意。尽管RDBMS最近得到了很多垃圾话,但它们的表现通常比你预期的要好得多,并且表现得非常好。他们通常也会为您的问题提供最简单可靠的解决方案 - 20多年的开发相当于某些东西。 在我工作的地方,我们使用MS-SQL作为每天处理数十亿个事务的Web应用程序,其中一些数据库达到数亿行和数TB的存储。我们也使用NoSQL(Riak,Couch,HBase) - 但只有SQL根本无法使用。您的系统不是这种情况。
答案 1 :(得分:0)
引用Knuth的话说,“过早优化是编程中所有邪恶(或至少大部分)的根源。”任何模糊的现代数据库应该能够处理表中的数百万行,因此365行/酒店/年将在成为问题之前扩展到相当多的酒店。您建议的优化会带来很大的维护成本,因为您的查询变得难以手动调试。它还使得索引表变得更加困难,这是一个重大损失,因为大多数RDBMS系统都能充分利用索引,但却没有很好地优化查询中的bitmath。
我会等到你真的拥有一个编写良好的索引数据库,并且在查看类似这样的内容之前,你已经将系统中的瓶颈隔离了,老实说我可能会考虑从传统的RDBMS转移到某种东西在尝试此方案之前,可能会分发,可能是MongoDB或Cassandra。