问题1:假设有50万家酒店的数据、每家酒店有1~数十种房型不等、每家酒店有若干个供应商(也是从1个到数十个不等);每个供应商对每个房型提供的房价在理论上一年365天都可能不同,请问怎么设计结构能让用户方便的查询某晚或某几晚的房价?
问题2:假设有全球10万条航线的数据、每条航线每天有0~数十架次的航班(起飞时间不同)、每个航班还分若干个舱段(如头等舱、商务舱、经济舱)、每个舱段有若干个供应商(也是从1个到数十个不等);每个供应商提供的价格都不同,怎么设计结构能让用户方便的查询某条航线某天(或某天指定时段:如12点到15点)、或者某几天内该航线的价格。
PS:(1)酒店房价越临近“今天”变动越频繁,航线价格的变化更加频繁;
(2)时效性:“昨天”的酒店不能买、距飞机起飞若干小时之前的机票也不能买。
MongoDB模式设计,特别是设计到性能要求很高的时候,必须按照你的查询模式来。你要列出最最频繁使用的几个查询,然后根据这些高频查询做相应的设计。比如说,你说让用户查询某晚房间的价格,系统会允许什么样的查询条件? 按照范围、商区,地理位置,酒店类型,星级? 查询结果要按什么排序?查询多晚的时候是否需要把价格汇总?
eshujiushiwo 所推荐的设计会有最小的冗余度 – 酒店信息不需要重复。当然如果酒店,房型信息基本不变,变的只是一部分日期的价格的话,可以考虑适当的冗余一些酒店数据,这样的话可以减少单个文档的大小,易于做一些聚合运算(特别是多晚的场景)。 如:
{
hotel: {
id:xxx, name: ‘香格里拉’, star: 5, location:[ ], area:’中心区’
},
date: 2015-06-01,
room_type:’高级大床房’
rate: 1280
}
查找单晚的话:
db.col.find(
{‘hotel.area’:’中心区’, date: ‘2016-06-01’ }
).sort({rate:-1})
查找多晚,最便宜的酒店 (语句不一定准确)
db.col.aggregate(
[
{$match: {‘hotel.area’:’中心区’, date: {$gt:’2016-06-01′} , date:{$lt:’2016-06-05′}} },
{$group: {_id: {hid: “$hotel.id”,room:”$room_type”}, total: {$sum:”$rate”}} },
{$sort: {total:-1}}
)
由于日期和区域的过滤,用来做聚合的数据量不会特别大,可以满足mongo对聚合运算的内存限制。