业务需求
基于电影票售卖渠道的价格存储,某场次电影,不同销售渠道对应不同的价格。
业务分解
- schedule场次
- movie 影片
- channel 渠道:不同渠道对应不同价格,渠道数据有限最多几十个。
- price 价格
查询业务
- 根据场次查询某渠道的价格
- 根据渠道查询对应场次信息
解决方案1
{
schedule:'001',
movie:'王者归来',
price:{'gewala':30, 'maoyan':29, 'taopiao':32}
}
数据表达上无字段冗余非常紧凑,那么业务查询能力呢?
- 根据电影场次查询某渠道的价格
# 建立索引
> createIndex({shedule:1, movie:1})
可定位到唯一文档,对price没有创建索引优化,查询效率一般。
- 根据渠道查询对应的场次
为优化查询需对每个渠道分别建立索引
# 建立索引
> createIndex({price.gewala:1})
> createIndex({price.maoyan:1})
> createIndex({price.taopiao:1})
问题是渠道会虽然固定但会变化,为支持此种查询,想想维护起来是异常噩梦。
解决方案2
{
schedule:'001',
movie:'王者归来',
channel:'gewala',
price:30
}
{
schedule:'001',
movie:'王者归来',
channel:'maoyan',
price:29
}
{
schedule:'001',
movie:'王者归来',
channel:'taopiao',
price:32
}
相比方案1,方案2将整个存储对象结构进行扁平化处理,变成了表的结构,传统关系数据库多采用此种类型的方案。
信息表达上,把一个对象按渠道维度拆分成多个,其它字段进行冗余存储。
若业务需求在复杂点,造成的冗余信息膨胀非常巨大,膨胀后带来的副作用是磁盘空间占用上升,内存命中率降低等缺点。
查询处理
- 根据场次查询某渠道价格
# 建立索引
> createIndex({schedule:1, movie:1, channel:1})
- 根据渠道查询对应场次信息
# 建立索引
> createIndex({channel:1})
解决方案3
{
shedule:'001',
movie:'王者归来',
provider:[
{channel:'gewala', price:30},
{channel:'maoyan', price:29},
{channel:'taopiao', price:32}
]
}
使用MongoDB建模结果中的数组,查询方面可建立 Multikey Index索引。
- 根据渠道查询某渠道的价格
# 建立索引
> createIndex({schdule:1, movie:1, provider.channel:1})
- 根据渠道查询对应场次信息
# 建立索引
> createIndex({provider.channel:1})
开发人员在进行建模时会受到传统数据库的思想影响,沿用之前的思维惯性,而忽视了“文档”的价值。