MongoDB,如何选择合适的设计?

时间:2018-12-01 13:56:15

标签: mongodb

我必须创建一个文档集合,并且对正确的设计有疑问。

每个文档都是一个“身份”;每个身份都有“合作伙伴数据”列表;每个伙伴数据都由一个ID和一组数据定义。

一种方法可以是(1):

{
    _id: ...
    partners: [
        {
            id: partner1,
            data: {

            }
        },
        {
            id: partner2,
            data: {

            }
        },

    ]
}

另一种方法可以是(2)

{
    _id: ...
    partners: {
        partner1:  {
            data: {

            }
        },
        partner2: {
            data: {

            }
        },

    ]
}

我更喜欢第一个身份,但是考虑到我可能有上百万个身份,这可能是表现最好的模式吗?

一个典型的查询可以是:“有多少个身份与ID为N的伙伴”。

在第二个示例中,查询可以是:

db.identities.find({partner.partnerName:{$ exists:true}})

采用第一种方法时,如何获得此计数? 第二种解决方案更易于处理服务器端;每个文档都会有一个列表,其中每个KEY是合作伙伴ID,因此我不必扫描所有文档,而只需按键即可获取合作伙伴数据...

您如何看待这些解决方案?我更喜欢第一个,但第二个我认为更“可用” ...

谢谢

1 个答案:

答案 0 :(得分:0)

  

我更喜欢第一个身份,但是考虑到我可能有上百万个身份,这可能是表现最好的模式吗?

如果您要拥有数百万个身份,那么两种方法 并不是真正可扩展的。

mongo中的每个文档都有大小限制(16MB)(read about it here

如果您将拥有很多身份, 可扩展的方法是创建一个不同的集合, 仅用于关系和伙伴关系数据。

现在,我也希望您考虑如何对待“伙伴关系”, 如果我是用户,并且您将我列入了合作伙伴列表,那么您会把我视为您的合作伙伴吗?

如果我们俩都将对方视为伙伴,那么mongo-db可能不是最佳解决方案。图数据库更适合处理这种类型的关系。

mongo中用于双向关系的所有解决方案都将基于双重更新(您的ID在我的合作伙伴列表中,我的ID在您的合作伙伴列表中)。 (在SQL中,您可以添加一个附加条件,但不能在mongo中添加), 因此,您无需保存两次合作关系。 (我和你,你和我) 只有你和我。

你知道这是怎么回事吗?

如果您只需要走一条路, 然后只需创建第二个集合“伙伴关系”

{
  _id: should be uniqe,
  user_id: 'your_id',
  partner_id: 'his_id'
  data: {} or just flatten the fields into the root object.
}

请注意,您为每个合作伙伴创建一行!

然后,您可以使用$ lookup来查询具有所有用户的用户 合作伙伴。

类似:

db.getCollection('partners').aggregate([
  {
      $lookup: {
         from: 'parterships',
         localField: '_id',
         foreignField: 'user_id',
         as: 'partners'
      }
  },
  {
      $project: {
        name: 1,
        partners: 1,
        num_partners: { $size: "$partners" }
   }
  }
])

详细了解聚合阶段here

如果您将没有太多的合伙企业,那么请继续 您的第一种方法很好。

第二种方法将使对该集合的大多数查询变得很奇怪,并且您将始终必须编写代码才能查询该表。 它不会是“直接”的mongo查询。