MongoDB 设计模式集锦 - 解决具体问题。

  • 一个好的设计模式可以显著地 提升数据读写的效率降低资源的需求

  • 更多MongoDB的设计模式:

    表现形式类 数据访问类 组织结构类
    列转行 子集 分桶
    文档版本 近似处理 预聚合

下面开始具体的问题

问题1:大文档,很多字段,很多索引

  • 索引虽然提高了查询性能,但是在写入时 索引过多 会严重影响性能。
# 记录电影的各地区的上映日期
{
	title: "Dunkirk",
	...
	release_HK: "2017/07/20",
	release_USA: "2017/07/21",
	release_RUS: "2017/07/20",
	release_CHN: "2017/09/01",
	...
}
# 需要很多索引
{release_HK: 1}
{release_USA: 1}
{release_RUS: 1}
{release_CHN: 1}
...
  • 解决方案:列转行
{
	title: "Dunkirk",
	...
	releases: [
		{country: "HK", date: "2017/07/20"},
		{country: "USA", date: "2017/07/21"},
		{country: "RUS", date: "2017/07/20"},
		{country: "CHN", date: "2017/09/01"}
		...
	]
}
# 索引只需一个组合索引。
db.movies.createIndex({"releases.country":1,"releases.date":1})
  • 列转行 总结:

    场景 痛点 设计模式方案及优点
    产品属性'color', 'size', 'dimensions',...
    多语言(多国家)属性;
    文档中有很多同类型的类似字段;
    会用于组合查询搜索,需要建立很多索引;
    转化为数组,一个索引解决所有的查询问题。
问题2:Mongo中的灵活模型,如何管理文档的不同版本?

  • Mongo的模型虽然灵活了支持任意的属性增减,但是带来的问题就是数据的不确定性。
  • 解决方案:版本字段
# 2019.01 版本1.0
{
	"_id": ObjectId("5de26f197edd62c5d388babb"),
	"name": "TJ",
	"company": "Tapdata",
}

# 2019.03 版本2.0
{
	"_id": ObjectId("5de26f197edd62c5d388babb"),
	"name": "Tom",
	"company": "Tapdata",
	"wechat": "tom23333", # 新增了字段
	"schema_version": "2.0" # 版本号
}
  • 版本字段 总结:

    场景 痛点 设计模式方案及优点
    任何有版本衍变的数据库。 文档模型格式多,无法知道其合理性;
    升级时需要更新太多文档;
    增加一个版本号字段;
    快速过滤掉不需要升级的文档;
    升级时候对不同版本的文档做不同的处理;
问题3:统计网页点击流量

  • 每访问一个网页都会产生一次数据库计数更新操作,统计数字准确性并不十分重要

  • 解决方案:近似计算

    # 每次 +1, 加10次。
    for i in range(0,10)
    	{$inc:{views:1}}
    
    # 使用近似计算,十次访问每次随机,随机数触发一次 + 10。
    # 近似地每隔 10次(或n次)写一次。
    for i in range(0,10)
      if random(0,9) == 0
        increment by 10
    
  • 近似计算 总结:

    场景 痛点 设计模式方案及优点
    网页计数
    各种结果不需要准确的排名。
    写入太频繁,消耗系统资源。 间隔写入,每隔 10次或100次,大量减少写入需求。
问题4:业绩排名,游戏排名,商品统计等精确排名

  • 解决方案:预聚合字段 $inc

    {
    	id: 1003,
    	product: "Bike",
    	quantitiy:200394,  # 库存
    	daily_sales:40,    # 日销量
    	weekly_sales:302,  # 周销量
    	monthly_sales:1420,# 月销量
    }
    
    db.invertory.update(
    	{id: 1003},
    	{$inc:{
    		quantity:-1,
    		daily_sales:1,
    		weekly_sales:1,
    		monthly_sales:1
    	}}
    )
    
  • 预聚合 总结:

    场景 痛点 设计模式方案及优点
    准确排名
    排行榜
    商品热销榜,某商品的日销量/周销量/月销量
    电影排行,观影人次场次统计
    聚合计算消耗资源多,计算时间长。 模型中直接增加统计字段,每次更新数据时候同时更新统计值。

posted on 2021-03-30 15:10  Sweet小马  阅读(150)  评论(0编辑  收藏  举报

导航