【问题标题】:mongodb best practice: nestingmongodb最佳实践:嵌套
【发布时间】:2011-02-24 18:21:12
【问题描述】:

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

一个名为 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

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

  • 嵌套,但只有一层深度
  • 删除不必要的键
  • 利用数组让对象更灵活

    {
       "_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" 
          } 
        } 
    }
    

谢谢!

【问题讨论】:

    标签: mongodb database nosql


    【解决方案1】:

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

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

    嵌套总是好的,但是两到三层嵌套深度可能会在查询/更新时产生额外的麻烦。

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

    【讨论】:

    • +1,这消除了原始架构的一些人为限制,例如不允许用户在同一个国家/地区拥有多个地址。
    • 谢谢你,绝对有道理。为什么嵌套深度会导致查询/更新问题?
    • 更新中的主要问题,例如不能按条件更新两个深度嵌套数组。
    • 另外澄清一下 - 您是在建议电子邮件和地址应该是一个对象数组?
    • @Colin:是的,你是对的。因为如果将来您需要“新”类型的电子邮件或地址,您只需将其添加到收藏夹中即可。
    【解决方案2】:

    您可能想查看 MongoDB 中的 schema design,特别是有关 embedding vs. references 的建议。

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

    【讨论】:

    【解决方案3】:

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

    例如,如果您有一个地址列表并且需要更新其中的一个,那将是一件很麻烦的事情,因为您需要遍历所有地址或知道特定地址所在的位置。您可以放心,因为每个地址都有一个键值对。

    但是,我会说不要使用 basiccontact 键。这些真的给了你什么?如果您索引name,它将是basic.name 而不仅仅是name。 AFAIK,长键名和短键名对性能有一些影响。

    保持足​​够简单,以完成您需要做的事情。尝试一些东西并对其进行迭代......你不会第一次就做对,但 mongo 的好处是它可以相对容易地随时修改你的架构。

    【讨论】:

    • 没错,我想基本/联系人键没有真正的需要——除了保持整洁。
    【解决方案4】:

    这是可以接受的做法。在数组中嵌套数组存在一些问题。一个例子见SERVER-831。但是,您似乎根本没有在您的集合中使用数组。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-02
      • 2011-07-12
      • 1970-01-01
      • 2023-03-23
      • 2017-12-12
      • 2021-03-26
      • 2019-03-16
      相关资源
      最近更新 更多