MongoDB数据建模小案例:多列数据结构

本文涉及的产品
云原生数据库 PolarDB 分布式版,标准版 2核8GB
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
云数据库 RDS SQL Server,基础系列 2核4GB
简介: MongoDB数据建模小案例

需求

最近收到一个业务需求,需求是基于电影票售卖的不同渠道价格存储。某一个场次的电影,不同的销售渠道对应不同的价格。整理需求为:

  • 数据字段:

    1. 场次信息;
    2. 播放影片信息;
    3. 渠道信息,与其对应的价格;
    4. 渠道数量最多几十个;
  • 业务查询有两种:

    1. 根据电影场次,查询某一个渠道的价格;
    2. 根据渠道信息,查询对应的所有场次信息;

建模

不好的

我们先来看其中一种典型的不好建模设计:

{
  "scheduleId": "0001",
  "movie": "你的名字",
  "price": {
    "gewala": 30,
    "maoyan": 50,
    "taopiao": 20
  }
}

数据表达上基本没有字段冗余,非常紧凑。再来看业务查询能力:

  1. 根据电影场次,查询某一个渠道的价格;

    • 建立createIndex({scheduleId:1, movie:1})索引,虽然对price来说没有创建索引优化,但通过前面两个维度,已经可以定位到唯一的文档,查询效率上来说尚可;
  2. 根据渠道信息,查询对应的所有场次信息;

    • 为了优化这种查询,需要对每个渠道分别建立索引,例如:

      • createIndex({"price.gewala":1})
      • createIndex({"price.maoyan":1})
      • createIndex({"price.taopiao":1})
    • 但渠道会经常变化,并且为了支持此类查询,肯能需要创建几十个索引,对维护来说简直就是噩梦;

此设计行不通,否决。

一般般的设计

{
  "scheduleId": "0001",
  "movie": "你的名字",
  "channel": "gewala",
  "price": 30
}

{
  "scheduleId": "0001",
  "movie": "你的名字",
  "channel": "maoyan",
  "price": 50
}

{
  "scheduleId": "0001",
  "movie": "你的名字",
  "channel": "taopiao",
  "price": 20
}

与上面的方案相比,把整个存储对象结构进行了平铺展开,变成了一种表结构,传统的关系数据库多数采用这种类型的方案。信息表达上,把一个对象按照渠道维度拆成多个,其他的字段进行了冗余存储。如果业务需求再复杂点,造成的信息冗余膨胀非常巨大。膨胀后带来的副作用会有磁盘空间占用上升,内存命中率降低等缺点。对查询的处理呢:

  1. 根据电影场次,查询某一个渠道的价格;

    • 建立createIndex({scheduleId:1, movie:1, channel:1})索引;
  2. 根据渠道信息,查询对应的所有场次信息;

    • 建立createIndex({channel:1})索引;

更进一步的优化呢?

合理的设计

{
  "scheduleId": "0001",
  "movie": "你的名字",
  "provider": [
    {
      "channel": "gewala",
      "price": 30
    },
    {
      "channel": "maoyan",
      "price": 50
    },
    {
      "channel": "taopiao",
      "price": 20
    }
  ]
}

注意看,这里使用了在MongoDB建模中非常容易忽略的结构--”数组“。查询方面的处理,是可以建立Multikey Index索引,详细信息可以参考官方文档
]说明

  1. 根据电影场次,查询某一个渠道的价格;

    • 建立createIndex({scheduleId:1, movie:1, "provider.channel":1})索引;
  2. 根据渠道信息,查询对应的所有场次信息;

    • 建立createIndex({"provider.channel":1})索引;

    再通过explain来验证上面两个索引是否起到作用:

db.movie.find({"scheduleId":"0001","movie":"你的名字", "provider.channel":"taopiao"}).explain()

......
  "winningPlan": {
    "stage": "FETCH",
    "inputStage": {
      "stage": "IXSCAN",
      "keyPattern": {
        "scheduleId": 1,
        "movie": 1,
        "provider.channel": 1
      },
      "indexName": "scheduleId_1_movie_1_provider.channel_1",
      "isMultiKey": true,
......
db.movie.find({"provider.channel":"taopiao"}).explain()

......
  "winningPlan": {
    "stage": "FETCH",
    "inputStage": {
      "stage": "IXSCAN",
      "keyPattern": {
        "provider.channel": 1
      },
      "indexName": "provider.channel_1",
      "isMultiKey": true,
......

总结

这个案例并不复杂,需求也很清晰,但确实非常典型的MongoDB建模设计,开发人员在进行建模设计时经常也会受传统数据库的思路影响,沿用之前的思维惯性,而忽略了“文档”的价值。

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
4月前
|
存储 NoSQL MongoDB
【MongoDB】MongoDB 如何处理复杂的数据结构?
【4月更文挑战第2天】【MongoDB】MongoDB 如何处理复杂的数据结构?
|
28天前
|
JSON NoSQL MongoDB
MongoDB Schema设计实战指南:优化数据结构,提升查询性能与数据一致性
【8月更文挑战第24天】MongoDB是一款领先的NoSQL数据库,其灵活的文档模型突破了传统关系型数据库的限制。它允许自定义数据结构,适应多样化的数据需求。设计MongoDB的Schema时需考虑数据访问模式、一致性需求及性能因素。设计原则强调简洁性、查询优化与合理使用索引。例如,在构建博客系统时,可以通过精心设计文章和用户的集合结构来提高查询效率并确保数据一致性。正确设计能够充分发挥MongoDB的优势,实现高效的数据管理。
37 3
|
20天前
|
安全 C# 数据安全/隐私保护
WPF安全加固全攻略:从数据绑定到网络通信,多维度防范让你的应用固若金汤,抵御各类攻击
【8月更文挑战第31天】安全性是WPF应用程序开发中不可或缺的一部分。本文从技术角度探讨了WPF应用面临的多种安全威胁及防护措施。通过严格验证绑定数据、限制资源加载来源、实施基于角色的权限管理和使用加密技术保障网络通信安全,可有效提升应用安全性,增强用户信任。例如,使用HTML编码防止XSS攻击、检查资源签名确保其可信度、定义安全策略限制文件访问权限,以及采用HTTPS和加密算法保护数据传输。这些措施有助于全面保障WPF应用的安全性。
30 0
|
1月前
|
存储 NoSQL 关系型数据库
揭秘MongoDB:这个神奇的建模技巧将如何彻底改变你的数据结构?
【8月更文挑战第8天】MongoDB的灵活数据模型支持多种1对N关系建模方式。本文通过实例介绍两种主要方法:嵌入文档与引用文档。对于少量且稳定的子数据,如作者与书籍,可直接嵌入;若子数据量大或变动频繁,则采用引用以提高效率。每种方法均有优劣,需根据具体场景选择,以最大化利用MongoDB的优势。
34 0
|
3月前
|
NoSQL 物联网 atlas
智能制造案例专题|与MongoDB一起解锁工业4.0转型与增长的无限潜力!
欢迎访问MongoDB中文官网 https://www.mongodb.com/zh-cn 了解更多智能制造业的MongoDB解决方案
5387 2
|
3月前
|
NoSQL 物联网 atlas
|
4月前
|
NoSQL MongoDB 数据库
MongoDB数据恢复—MongoDB数据库文件被破坏的数据恢复案例
服务器数据恢复环境: 一台Windows Server操作系统服务器,服务器上部署MongoDB数据库。 MongoDB数据库故障&检测: 工作人员在未关闭MongoDB数据库服务的情况下,将数据库文件拷贝到其他分区。拷贝完成后将原MongoDB数据库所在分区进行了格式化操作,然后将数据库文件拷回原分区,重新启动MongoDB服务,服务无法启动。
|
4月前
|
存储 NoSQL 数据挖掘
MongoDB 实时分析案例
【5月更文挑战第7天】
135 0
|
9月前
|
NoSQL MongoDB 数据库
数据库数据恢复—Windows server环境下MongoDB数据库数据恢复案例
MongoDB数据库数据恢复环境: 一台Windows Server操作系统的虚拟机,虚拟机上部署有MongoDB数据库。 MongoDB数据库故障&检测: 在未关闭MongoDB服务的情况下,工作人员将MongoDB数据库文件拷贝到其他分区,然后将原数据库文件所在分区进行了格式化的操作,格式化完成后将数据库文件拷回原分区,重新启动MongoDB服务,发现MongoDB服务无法启动并报错。
数据库数据恢复—Windows server环境下MongoDB数据库数据恢复案例
|
9天前
|
存储 人工智能 C语言
数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值&&特殊矩阵的压缩存储
本文首先介绍了栈的应用之一——括号匹配,利用栈的特性实现左右括号的匹配检测。接着详细描述了南京理工大学的一道编程题,要求判断输入字符串中的括号是否正确匹配,并给出了完整的代码示例。此外,还探讨了栈在表达式求值中的应用,包括中缀、后缀和前缀表达式的转换与计算方法。最后,文章介绍了矩阵的压缩存储技术,涵盖对称矩阵、三角矩阵及稀疏矩阵的不同压缩存储策略,提高存储效率。