用于预订、嵌套或引用的 MongoDB 模式?

Posted

技术标签:

【中文标题】用于预订、嵌套或引用的 MongoDB 模式?【英文标题】:MongoDB schema for reservations, nested or referenced? 【发布时间】:2014-09-29 06:33:00 【问题描述】:

我正在为 MongoDB 设计我的第一个数据库,我想知道我是否朝着正确的方向前进。

它基本上是一个剧院的模拟预订系统。嵌套 2 或 3 层深有什么本质上的错误吗?

以后会不会对查询产生问题?

什么是性能和可用性方面的最佳解决方案?

我是否应该像对待预订的客户一样使用参考资料?

这是我目前所拥有的:

//shows

    
       _id: 2132131,
       name: 'something',
       screenplay: ['author1', 'author2'],
       show_type: 'children',
       plays:  
                  datetime: "O0:00:00 0000-00-00",
                  price: 120,
                  seats: 
                          
                            _id:['a', 1],
                            status: 'reserved',
                            client: 1
                          ,

                          
                            _id:['a', 2],
                            status: 'reserved',
                            'client:1
                          
                
    



//clients

    
      _id:1,
      name: 'Julius Cesar',
      email: 'julius@rome.com',
    

【问题讨论】:

【参考方案1】:

您可能会听到对此的不同看法,但让我与您分享我的看法。

首先,您的架构似乎不适合您的用例。您很可能希望“播放”是一个数组而不是一个对象,所以:

  
   "_id":2132131,
   "name":"something",
   "screenplay":[  
      "author1",
      "author2"
   ],
   "show_type":"children",
   "plays":[  
        
         "datetime":"O0:00:00 0000-00-00",
         "price":120,
         "seats":[  
              
               "_id":[  
                  "a",
                  1
               ],
               "status":"reserved",
               "client":1
            ,
              
               "_id":[  
                  "a",
                  2
               ],
               "status":"reserved",
               "client":1
            
         ]
      
   ]

如果我的假设是正确的,那么您现在有双嵌套数组,这是一种极其不切实际的模式,因为您不能在查询或更新中使用多个位置运算符。

尽管大多数 NoSQL 人群似乎认为实际上只有少数有效用例可以将 集合 嵌入到文档中。需要满足以下条件:

嵌入式集合在大小方面有非常明确的上限。在变得笨拙/低效之前,此限制不应高于几十个。 嵌入式集合不应定期增长(这会导致文档在磁盘上移动,从而显着降低性能) 嵌入集合中的元素不应包含数组属性(当前查询语言不允许您修改双嵌套数组的特定元素) 您永远不应要求嵌套集合的元素,而不必查询包含该嵌入集合的根文档。

您会发现满足上述所有条件的情况并不多。其中一些标准有些主观,但轻量级引用实际上并没有那么复杂。实际上,无法“原子地”修改不同集合中的文档是唯一的复杂情况,您会发现这并不像在大多数情况下听起来那么大。

TL;DR : 不要重复嵌套数组;将“播放”放在单独的集合中

【讨论】:

【参考方案2】:

通常,您应该始终更喜欢在 MongoDB 中嵌入而不是引用,因此您已经朝着正确的方向前进。

对 1:n 关系使用引用的唯一原因是当您有不断增长的对象时,因为导致文档大小增长的更新可能会很慢。但是,您似乎正在处理不会非常频繁地增长(可能一天几次)的数据,这可能意味着您不应该遇到性能问题。

【讨论】:

以上是关于用于预订、嵌套或引用的 MongoDB 模式?的主要内容,如果未能解决你的问题,请参考以下文章

用于预订房间的 MongoDB 架构应该是啥?

用于多个对象数组的猫鼬嵌套模式

在 Mongodb 中查询嵌套模式?

mongodb:使用嵌套文档或带有引用的单独集合

MongoDB:用于搜索性能的嵌套值与单独的集合 - 数据库模式设计

GraphQL 嵌套文档在突变时返回 null