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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
简介: 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
目录
相关文章
|
1月前
|
存储 NoSQL MongoDB
【MongoDB】MongoDB 如何处理复杂的数据结构?
【4月更文挑战第2天】【MongoDB】MongoDB 如何处理复杂的数据结构?
|
8天前
|
NoSQL 物联网 atlas
|
29天前
|
存储 NoSQL 数据挖掘
MongoDB 实时分析案例
【5月更文挑战第7天】
|
1月前
|
NoSQL MongoDB 数据库
MongoDB数据恢复—MongoDB数据库文件被破坏的数据恢复案例
服务器数据恢复环境: 一台Windows Server操作系统服务器,服务器上部署MongoDB数据库。 MongoDB数据库故障&检测: 工作人员在未关闭MongoDB数据库服务的情况下,将数据库文件拷贝到其他分区。拷贝完成后将原MongoDB数据库所在分区进行了格式化操作,然后将数据库文件拷回原分区,重新启动MongoDB服务,服务无法启动。
|
6月前
|
NoSQL MongoDB 数据库
数据库数据恢复—Windows server环境下MongoDB数据库数据恢复案例
MongoDB数据库数据恢复环境: 一台Windows Server操作系统的虚拟机,虚拟机上部署有MongoDB数据库。 MongoDB数据库故障&检测: 在未关闭MongoDB服务的情况下,工作人员将MongoDB数据库文件拷贝到其他分区,然后将原数据库文件所在分区进行了格式化的操作,格式化完成后将数据库文件拷回原分区,重新启动MongoDB服务,发现MongoDB服务无法启动并报错。
数据库数据恢复—Windows server环境下MongoDB数据库数据恢复案例
|
7月前
|
存储 NoSQL Java
微服务技术系列教程(46)-SpringBoot整合MongoDB(文章评论案例)
微服务技术系列教程(46)-SpringBoot整合MongoDB(文章评论案例)
138 0
|
7月前
|
存储 NoSQL 关系型数据库
数据库数据恢复——MongoDB数据库数据恢复案例
MongoDB数据库是文档数据存储库,将文档存储在集合之中,不是像MySQL一样的关系型数据库。 MongoDB数据库是开源数据库,同时提供具有附加功能的商业版本。 MongoDB数据库中的数据是以键值对(key-value pairs)的形式显示的,因此在模式设计上数据库受到的约束少,非常适合具有快速增长或其他变化需求的数据。
数据库数据恢复——MongoDB数据库数据恢复案例
|
10月前
|
存储 NoSQL 数据建模
MongoDB性能系列最佳实践-数据建模与内存优化
帮助用户在多个关键方面实现规模化性能优化
MongoDB性能系列最佳实践-数据建模与内存优化
|
12月前
|
存储 NoSQL 安全
【MongoDB行业案例】Bosch IoT 和应用程序驱动型分析的重要性
将运营和分析工作负载整合到一处的数据平台
|
消息中间件 数据采集 NoSQL
《Apache Flink 案例集(2022版)》——1.数据集成——XTransfer-基Flink MongoDB CDC 在 XTransfer 的生产实践(上)
《Apache Flink 案例集(2022版)》——1.数据集成——XTransfer-基Flink MongoDB CDC 在 XTransfer 的生产实践(上)
168 0