基本的mongodb理论

这无疑是一个愚蠢的问题,当答案指出它的一切简单明了,但在关系数据库的艺术中被坚定地灌输出来时,我们都可以笑到它有多愚蠢,我似乎无法得到我的头完全围绕着mongodb--无论我看过多少文章或看过的视频。

这是我的情况。 我有一个可能会有数百万用户的项目。 核心功能:

  • 有一个4种不同类型的用户列表
  • 其中一种类型的用户可以创建事件
  • 其他用户类型可以申请在活动中执行(然后在申请方和组织方之间有一个请求系统来就条款达成一致)
  • 其他用户类型可以参加该活动
  • 所有用户类型都可以遵循该事件
  • 每个用户都可以将无限量的图片上传到他们的“画廊”
  • 现在我马上知道如何去规范MySQL数据库并加入查询来获取我需要的数据,但是mongodb呢?

    由于所有这些信息都与用户有关系吗?我只是为用户创建一个集合吗? 对于每个用户,我是否创建一个文档? 这个文件是否存储了与该用户相关的所有事件,请求和图像的所有细节 - 或者这些事物的某种形式,然后我交叉参考? 如果不是这样,这不会复制大量数据 - 也就是说,如果我必须复制每个用户在该事件之后/参加/执行的所有事件数据并将其放入该用户文档中(我肯定情况并非如此 - 但没有连接,如果事件存储在另一个集合中,我如何才能“加入”用户和所有事件数据?)。 怎么样的图像? 用户文档可以是16MB - 但是如果我允许无限制的图像,并且与用户相关的所有内容都存储在单个文档中,那么单独的图像可能会比单个文档增大?

    我确定我对理解mongodb不是很重要 - 开导我!

    谢谢。


    您可以使用2个不同的用户和事件集合来设计您的应用程序。 像这样的东西

    UserDocument Collection
        -Type
        -Details    
    
    EventDocument Collection
        -Created By
        -EventDetail
        -AppliedUsers
             -"User A",User B"
        -AttendingUsers
             -"User C",User D"
        -FollowingUsers
             -"User E",User F"
    

    事件文档得到了应用的所有用户标识,使用Dbref参与和跟踪用户。

    另一种方法是将经常访问的用户文档字段与DBref对象一起存储。 这样可以避免对数据库的不必要命中和在文档中存储冗余(完整的用户数据)数据。 就像是

     EventDocument Collection
        -Created By
        -EventDetail
        -AppliedUsers
             -"User"
                 - Name
                 - XXX
                 - DbRef to User A
        -AttendingUsers
             -"User"
                 - Name
                 - XXX
                 - DbRef to User B
    
        -FollowingUsers
             -"User"
                 - Name
                 - XXX
                 - DbRef to User C
    
             -"User"
                 - Name
                 - XXX
                 - DbRef to User D
    

    对于图像,您可以使用GridFs。 这会将大文件分割成更小的块。


    最初我建议只创建UserDocument并在用户内部嵌入所有与事件有关的集合,将来您会看到事件是否会成为大集合(更多的是mongodb限制4mb),您将把它移动到单独的集合中。 至于图像看mongodb gridFs功能,它允许您存储任何大小的文件。 在用户文档中,您只能存储fileId的集合。

    当你开始设计文档数据框模式时,总是从嵌入事件开始,随后你会看到你需要的东西移到单独的集合中。 在你的情况下,如果你需要例如显示所有事件的列表,你不容易做到这一点,因为你需要加载每个用户并获得嵌入的事件集合,在这种情况下需要将事件移动到单独的集合中。

    更新:

    因为您需要从任何用户文档引用事件,所以您需要将事件移动到单独的集合中,因为引用嵌入的集合总是很糟糕。

    所以在与我自己讨论后,在我看来,下面的计划应该适合你需要:

    UserDocument Collection
        -UserId
        -Type
        -Details    
        -Events(EventId)
        -AppliedEvents
        -AttendingEvents
        -Files(it's not actual files it just references to gridFs filess)
    
    EventDocument Collection
        -EventId
        -EventDetail   
        -FollowingUsers
    

    我几乎把所有的东西都搬到了UserDocument中,因为User是一个'强壮'的实体,你将与事件一起工作(对我来说似乎是这样)。


    您应该遵循@ Bugai13和@Ramesh Vel关于您的数据库,图像和DBRefs设计的建议。 我只是想澄清一些事情。

    如果不是这样,这不会复制大量数据 - 也就是说,如果我必须复制每个用户在该事件之后/参加/执行的所有事件数据并将其放入该用户文档

    当存储成本很高时,人们在关系数据库中提出了规范化 - 因此将数据分成多个数据并使用连接重构它们。 现在存储相对来说非常便宜,如果你需要性能,重复数据不会被人忽视。 然而,它取决于应用程序,但是,您的查询模式,您正在存储的数据量以及您所读取/写入的速度。 但是,你会说,不会写更多(因为没有正常化)导致更糟糕的表现? 不一定,取决于应用程序。 如果你担心这个问题,看看分片(对于MongoDB:http://www.mongodb.org/display/DOCS/Sharding+Introduction)。

    但没有连接,如果事件存储在另一个集合中,我如何才能“加入”用户和所有事件数据?

    还要注意的是,据我所知(很高兴能够纠正),MongoDB中没有“连接”操作。 这只发生在一些司机身上。 正如文档在这里所说:

    DBRef的优点是允许可选的自动客户端解引用一些驱动程序

    请注意,解引用仅在客户端发生,并且只发生在“某些”驱动程序中。 据我所知,PHP的确如此,但Java驱动程序并没有这样做 - 您必须通过从独立集合中提取两个结果集并手动加入它们来处理应用程序级别的连接,尽管使用了DBRef。

    链接地址: http://www.djcxy.com/p/50923.html

    上一篇: Basic mongodb theory

    下一篇: Is there a legal way to print tuples and pairs using operator<<?