Mongodb数据模型策略指导/建议

时间:2014-11-07 16:30:17

标签: node.js mongodb mongoose

我刚开始使用node和mongodb,并试图了解如何最好地构建数据(来自一生的sql)。

所以我最终得到了一个主要嵌入的数据结构,我相信这些关系是合乎逻辑的,但在我走得太远之前会想要一些外部反馈。兔子洞!

这是我提出的新mongodb数据模型:

user
    name (string)
    email (string)
    avatar (string)
    password (string)
    newsletter (binary)

account
    admins
        user (objectId)
    name (string)
    logo (string)
    sub (number)
    stripe (string)
    property
        users
            user (objectId)
            party (number)
            role (number)
            admin (binary)
        name (string)
        ecd (date)
        complete (binary)
        activity
            description (string)
            user (objectId)
            time (date)
        task_group
            position (number)
            name (string)
            task
                assinged
                    user (objectId)
                    complete (binary)
                name (string)
                description (string)
                due (date)
                visibility (number)
                comment
                    user (objectId)
                    time (date)
                    comment (string)

以前(我正在重建现有的sql应用程序)有很多表纯粹用于桥接数据,即account_link用于连接用户帐户(多对多)等。这些现在已经嵌入式,允许更直观的结构。鉴于嵌入式数据只需要在其父级的上下文中进行访问,我想想这是可行的方法。

我担心的是某些子文档会变得非常大。我是否必须担心子文档中包含多少数据?或者我应该像对待桌子一样对待子文档?也就是说,如果发现每个task_group包含400,000个任务,那么这个不必要的“膨胀”是否会发生。一个property?是否有一点可以将这些内容拆分出来并创建“链接表格”。纯粹出于实际/性能原因?或者我只是如此坚持sql心态,这只是感觉错误?

更新

鉴于收到和引用的建议,我相信我已经制作了更合适的设计,尽管如其他地方所述,它更像是一门艺术,而不是一门科学。反馈仍然欢迎!

重要注意事项:

我不会重新撰写链接的博文,但总结一下:

  • 如果基数是一对一并且不需要访问父对象上下文之外的嵌入对象,则嵌入N端
  • 如果基数是一对多或者由于任何原因N端对象应该独立,则使用对N侧对象的引用数组
  • 如果基数是一对一的话,请使用对N面对象中单面的引用

我还考虑了其​​中一个答案中提到的增长/文档大小一致性。

USER
    name (string)
    email (string)
    avatar (string)
    password (string)
    newsletter (binary)

ACCOUNT
    admins (USER reference array)
    name (string)
    logo (string)
    sub (number)
    stripe (string)
    properties (PROPERTY reference array)

PROPERTY
    name (string)
    ecd (date)
    complete (binary)
    users
        user (USER objectId)
        party (number)
        role (number)
        admin (binary)
    activity
        description (string)
        time (date)
    task_groups (TASK_GROUP reference array)

TASK_GROUPS
    property (PROPERTY objectId)
    position (number)
    name (string)
    task
        assigned
            user (USER objectId)
            complete (binary)
        name (string)
        description (string)
        due (date)
        visibility (number)
        comment
            user (USER objectId)
            time (date)
            comment (string)

3 个答案:

答案 0 :(得分:1)

enter image description here

enter image description here

在我解释之前看看这些照片:

集合中的每个文档在文档增长时都有自己的位置和空间,并且集合和集合上没有足够的空间,并且留下了自由空间 例如,你有帖子集合,它有嵌入的集合评论

post {
  _id:ObjectId('101');
  comments:[{author:'john',text:'some text'},{author:'mike',text:'some text'}]
}

当你只能添加一两个或三个注释时,这个模型很有用,但是当你可以根据需要推送注释时,你必须用引用来编写文档 将有收集和评论收集

收集后文件:

{
_id:ObjectId('101')
}

评论收集文件:

  {
    _id:ObjectId('10001'),
    _postId:ObjectId('101'),//references to post collection document!
    text:'some text',
    author:'john'
    }

答案 1 :(得分:0)

http://docs.mongodb.org/manual/tutorial/model-embedded-one-to-one-relationships-between-documents/ 这里有关于

的文档

1)模型一对一的关系 2)与嵌入式文档的模型一对多关系 3)与文档参考的模型一对多关系

阅读所有三段

我只会说嵌入式文档变得非常大,你必须使用未嵌入的文档引用

答案 2 :(得分:0)

我甚至会把任务从任务组中分离出来,并让它所属的组成为任务的属性。您可能想要查询组中的每个任务。只要你知道它属于哪个任务,你就可以做到。

但您可能还想查找特定任务,但有关其所属组或组的信息可能仍然与该任务相关。如果以这种方式在任务组中嵌入任务,则限制应用程序必须弄清楚任务可能属于哪个类别/组。可能这些组的功能更像是过滤器,在这些组中查找具有此描述的任务。

当您考虑如何查询时,您可能希望对这些结构执行的不同查询变得更加明显。下一步是从查询和构建模型索引。如果您有嵌入文档的索引,它应该是与原始文档相关的单独模型。但这也取决于嵌入式文档依赖于其上方结构中的属性的程度。

TL;博士;

我发现一个常见的经验法则是,如果你进行大量的读取操作,而且嵌入式文档的写入非常少,则可以嵌入。如果有大量的写入和读取,您将需要分离嵌入式特性。