mongodb最佳实践:筑巢

时间:2011-02-24 18:21:13

标签: mongodb database nosql

这个嵌套示例是否被普遍认为是好的或坏的做法(以及为什么)?

一个名为users的集合:

user
    basic
        name : value
        url : value
    contact
        email
            primary : value
            secondary : value
        address
            en-gb
                address : value
                city : value
                state : value
                postalcode : value
                country : value
            es
                address : value
                city : value
                state : value
                postalcode : value
                country : value

编辑:从这篇文章的答案中我已经使用以下规则更新了架构(数据与上面略有不同):

  • Nest,但只有一层深度
  • 删除不必要的密钥
  • 利用数组使对象更加灵活

    {
       "_id": ObjectId("4d67965255541fa164000001"),
       "name": {
         "0": {
           "name": "Joe Bloggs",
           "il8n": "en" 
          } 
        },
       "type": "musician",
       "url": {
         "0": {
           "name": "joebloggs",
           "il8n": "en" 
          } 
        },
       "tags": {
         "0": {
           "name": "guitar",
           "points": 3,
           "il8n": "en" 
          } 
        },
       "email": {
         "0": {
           "address": "joe.bloggs@example.com",
           "name": "default",
           "primary": 1,
           "il8n": "en" 
          } 
        },
       "updates": {
         "0": {
           "type": "news",
           "il8n": "en" 
          } 
        },
       "address": {
         "0": {
           "address": "1 Some street",
           "city": "Somecity",
           "state": "Somestate",
           "postalcode": "SOM STR",
           "country": "UK",
           "lat": 49.4257641,
           "lng": -0.0698241,
           "primary": 1,
           "il8n": "en" 
          } 
        },
       "phone": {
         "0": {
           "number": "+44 (0)123 4567 890",
           "name": "Home",
           "primary": 1,
           "il8n": "en" 
          },
         "1": {
           "number": "+44 (0)098 7654 321",
           "name": "Mobile",
           "il8n": "en" 
          } 
        } 
    }
    

谢谢!

4 个答案:

答案 0 :(得分:11)

在我看来,上面的架构不是“普遍接受”,但看起来很棒。但我建议一些改进,以帮助您将来查询您的文档:

User
    Name 
    Url
    Emails {email, emailType(primary, secondary)}
    Addresses{address, city, state, postalcode, country, language}

嵌套总是很好,但是两层或三层嵌套可以在查询/更新时产生额外的麻烦。

希望我的建议能帮助您正确选择架构设计。

答案 1 :(得分:6)

您可能需要查看MongoDB中的schema design,特别是embedding vs. references上的建议。

首选嵌入为“然后将数据放在磁盘上;消除了数据库的客户端 - 服务器周转”。如果父对象在RAM中,那么对嵌套对象的访问将始终很快。

答案 2 :(得分:5)

根据我的经验,我从来没有找到任何关于MongoDB记录实际外观的“最佳实践”。真正回答的问题是,“这个MongoDB模式是否允许我做我需要做的事情?”

例如,如果你有一个地址列表并需要更新其中一个地址,那就太麻烦了,因为你需要遍历所有地址或知道特定地址所在的位置。你之所以安全,因为每个地址都有一个键值。

但是,我会说basiccontact键。这些真正给你带来了什么?如果您为name编制索引,那么它将是basic.name,而不仅仅是name。 AFAIK,对长键和短键名称有一些性能影响。

保持简单,做你需要做的事。尝试一下并迭代它......你不会在第一次就把它弄好,但关于mongo的好处是你可以相对容易地重新设计你的模式。

答案 3 :(得分:1)

这是可以接受的做法。将数组嵌套在数组中有一些问题。有关示例,请参阅SERVER-831。但是,您似乎根本没有在集合中使用数组。

相反,如果您要将其分解为多个集合,则必须处理数据访问代码中缺少事务和由此产生的竞争条件。