MongoDB数据建模小案例:多列数据结构
2024-10-16 22:38:43 | 作者: 匿名
最近接到一个业务需求,是基于电影票销售不同渠道的价格存储。对于某一部电影,不同的销售渠道对应着不同的价格。整理要求是:
数据字段:
活动信息;
播放视频信息;
渠道信息及其对应的价格;
通道数可达数十个;
业务查询有两种类型:
根据电影放映数量查看某个频道的价格;
根据通道信息,查询所有对应的事件信息;
造型
坏的
我们先来看看一种典型的**糟糕**的建模设计:
{ 'scheduleId': '0001', '电影': '你的名字', 'price': { 'gewala': 30, 'maoyan': 50, 'taopiao': 20
}
}
数据表达基本没有字段冗余,非常紧凑。我们看一下业务查询能力:
根据电影放映数量查看某个频道的价格;
建立createIndex({scheduleId:1, movie:1})索引。虽然没有针对价格进行索引创建优化,但通过前两个维度可以定位到唯一文档,查询效率尚可;
根据通道信息,查询所有对应的事件信息;
createIndex({'price.gewala':1})
createIndex({'price.maoyan':1})
createIndex({'price.taopiao':1})
为了优化这种查询,需要对每个通道单独建立索引,例如:
但通道频繁变化,为了支持这样的查询,可能需要创建几十个索引,这对于维护来说简直就是噩梦;
这个设计行不通,被拒绝了。
马马虎虎的设计
{ 'scheduleId': '0001', '电影': '你的名字', '频道': 'gewala', '价格': 30}
{ 'scheduleId': '0001', '电影': '你的名字', '频道': '猫眼', '价格': 50}
{ 'scheduleId': '0001', '电影': '你的名字', '频道': '淘票票', '价格': 20}
与上述方案相比,整个存储对象结构被扁平化,变成了表结构。大多数传统关系数据库都采用这种解决方案。在信息表达上,将一个对象按照通道维度拆分为多个对象,其他字段进行冗余存储。如果业务需求比较复杂,由此带来的信息冗余膨胀将会是巨大的。扩展的副作用包括磁盘空间使用增加、内存命中率降低等缺点。查询处理怎么样:
根据电影放映数量查看某个频道的价格;
创建createIndex({scheduleId:1,movie:1,channel:1})索引;
根据通道信息,查询所有对应的事件信息;
创建createIndex({channel:1})索引;
进一步优化如何?
设计合理
{ 'scheduleId': '0001', '电影': '你的名字', '提供商': [
{ '频道': '格瓦拉', '价格': 30
},
{ '频道': '猫眼', '价格': 50
},
{ '渠道': '淘票票', '价格': 20
}
]
}
注意,这里使用了MongoDB 建模中容易被忽视的一个结构——“数组”。对于查询处理,可以建立多键索引。详细信息请参考官方文档。
]阐明
根据电影放映数量查看某个频道的价格;
创建createIndex({scheduleId:1, movie:1, 'provider.channel':1}) 索引;
根据通道信息,查询所有对应的事件信息;
创建createIndex({'provider.channel':1})索引;
然后使用explain验证上面两个索引是否有效:
db.movie.find({'scheduleId':'0001','电影':'你的名字','provider.channel':'taopiao'}).explain()……
'winingPlan': { 'stage': 'FETCH', 'inputStage': { 'stage': 'IXSCAN', 'keyPattern': { 'scheduleId': 1, '电影': 1, 'provider.channel': 1
}, 'indexName': 'scheduleId_1_movie_1_provider.channel_1', 'isMultiKey': true,
db.movie.find({'provider.channel':'taopiao'}).explain()……
'winingPlan': { 'stage': 'FETCH', 'inputStage': { 'stage': 'IXSCAN', 'keyPattern': { 'provider.channel': 1
}, 'indexName': 'provider.channel_1', 'isMultiKey': true,
相关视频
-
室外篮球哪个牌子好耐打(篮球爱好者必备的室外球品牌推荐)(室外篮球哪个牌子好用)
2023-09-07
-
NA2012季后赛热火对凯尔特人(2012热火vs凯尔特人揭幕战)
2023-09-07
-
世预赛积分榜2021(世预赛积分榜亚洲出现要求)
2023-09-07
-
坎特雷拉公主攻略(坎特雷拉故事)
2023-09-07
-
谢尔盖米林科维奇萨维奇
2023-09-07
-
最新黎巴嫩球联赛排名及球队析(黎巴嫩篮球联赛比分)
2023-09-07
-
郎平的事迹介绍及其他名人的成功经历(郎平的名人故事)
2023-09-07
用户评论
这个MongoDB数据建模的小案例真的很实用,我之前一直觉得多列数据结构挺复杂的,现在一看原来可以这样操作。
有18位网友表示赞同!
多列数据结构确实方便,但是维护起来有点头疼,希望这个案例能帮我解决一些问题。
有12位网友表示赞同!
案例里的多列数据结构处理方式挺巧妙的,学到了!
有15位网友表示赞同!
看了这个案例,我觉得MongoDB的数据建模其实并没有想象中那么难。
有14位网友表示赞同!
案例中的数据建模方法挺有创意的,但是我个人还是更喜欢关系型数据库。
有15位网友表示赞同!
多列数据结构在MongoDB里真是个好东西,特别是处理复杂查询时。
有15位网友表示赞同!
这个案例让我对MongoDB的多列数据结构有了更深入的理解。
有18位网友表示赞同!
案例中的多列数据结构有点复杂,我需要多看几遍才能完全消化。
有11位网友表示赞同!
对于新手来说,这个MongoDB数据建模小案例可能有点难度,但是值得一试。
有13位网友表示赞同!
案例中的多列数据结构处理方式很实用,但我感觉对于大数据量来说可能会有性能瓶颈。
有17位网友表示赞同!
这个案例让我对MongoDB的数据建模有了新的认识,谢谢分享!
有18位网友表示赞同!
多列数据结构在MongoDB中确实很有用,但是有时候也会造成数据冗余。
有9位网友表示赞同!
案例中的数据建模方法挺不错的,但是我觉得对于一些特定场景可能需要调整。
有5位网友表示赞同!
看了这个MongoDB数据建模案例,我觉得多列数据结构确实可以解决很多问题。
有10位网友表示赞同!
这个案例让我对MongoDB的数据建模有了新的启发,以后工作中会尝试使用。
有18位网友表示赞同!
多列数据结构在MongoDB中应用广泛,这个案例给了我很实用的指导。
有10位网友表示赞同!
案例中的多列数据结构处理方法很实用,但是我希望作者能进一步解释一下性能优化的问题。
有17位网友表示赞同!
这个MongoDB数据建模小案例让我对多列数据结构有了全新的认识,太感谢了!
有18位网友表示赞同!