如何在MongoDB中建模多对多关系(对于MySQL用户)

时间:2011-11-30 17:22:00

标签: mysql mongodb database-schema schema-design

我来自MySQL背景,我试图绕着MongoDB。特别是,我正在努力概念化我应该如何模仿n:n关系“Mongo方式”。

对于此示例,假设我们有两个collectionsusersinterests。我们需要能够在数据中表示或查询几件事情:

  • 用户的兴趣
  • 用户的兴趣评分,例如“喜欢”或“不喜欢”
  • 有兴趣的用户
  • 每个兴趣评级的计数器(可递增/递减)
  • 兴趣名称

MySQL中,我会在用户ID 兴趣ID上创建一个users_interests表。对于计数器,我会为每种评级类型设置单独的列,并且每次用户对兴趣进行评级/未评级时,都会执行一项事务以确保计数永远不会错误。

我试过reading about some schema designs,但无济于事。

你能帮助迷失的灵魂找到方向吗?

2 个答案:

答案 0 :(得分:11)

好问题。让我先概述一下N:N关系的工作原理,然后我将详细介绍每个要点。

N:N在MySQL中,通常您的数据透视表会在您的用户和兴趣(user_interests表)之间进行关联。在mongo你这样做有点不同。您仍然拥有用户和兴趣集合,但现在,您可以存储用户感兴趣的密钥列表。这样的事情:

User Collection {
      "name":"Josh",
      "user":"jsmith",
      "interests":[
           {
            "_id":12345,
            "rating":"like"
           },
           {..}..
      ]
}

通过将您的兴趣存储在您感兴趣的表格中的关键列表中,您可以执行所需的每项操作。如果您想进行查询,请根据兴趣表中的ID进行查询,然后使用$in modifier进行查询。

现在为了您的兴趣收集我会做以下事情:

User Interest {
      "_id":objectId
      "label":"Swimming",
      "count":intValue
}

当向用户文档添加兴趣时,count变量将取决于您的评级的定义。如果您将评级存储在单独的区域(或逻辑)中,那么您分配给它们的值将与您感兴趣的int值相关。 IE:用户将其评为meh(值为1),然后将计数值加1。

希望这很有帮助,至少带来了一些关于如何构建它的其他想法!

祝你好运,记住MONGO真棒。

答案 1 :(得分:1)

要维护每个兴趣的评级的全局计数,您将需要一个单独的独立集合,您可以使用原子更新运算符更新(添加或减少)评级,以及何时/不喜欢用户执行兴趣的操作。

您可以将每个用户的兴趣存储为用户集合本身的子文档数组。

此数据的JSON结构类似于:

db.User
{
    name: 'joe',
    ....,
    interests : [{ name: 'swimming', rating: 10},
              { name: 'cooking', rating: 22 }
              ]
}

现在您可以使用以下方式查询内部密钥:

> db.User.find( { "interests.name" : "cooking" } )

这将返回特别感兴趣的用户。