MongoDB数据库架构设计

时间:2012-06-06 17:13:04

标签: mongodb android-activity stream

我有一个拥有500,000用户的网站(在sql server 2008上运行)。我想现在包括用户及其朋友的活动流。在SQL Server上测试了一些东西后,很明显RDMS不是这种功能的好选择。它很慢(即使我严重地对我的数据进行了规范化)。因此,在查看其他NoSQL解决方案后,我认为我可以使用MongoDB。我将根据 activitystrea.ms 关注数据结构 json specifications for activity stream 所以我的问题是:MongoDB中活动流的最佳模式设计是什么(有了这么多用户,你几乎可以预测它在写入时非常繁重,因此我选择了MongoDB - 它具有很好的“写入”性能。我已经考虑了3种类型的结构,请告诉我这是否有意义,或者我应该使用其他模式模式。

1 - 以这种模式将所有朋友/粉丝存储在每个活动中:

 

    {
     _id:'activ123',
     actor:{
            id:person1
            },
    verb:'follow',
    object:{
            objecttype:'person',
            id:'person2'
            },
    updatedon:Date(),
    consumers:[
            person3, person4, person5, person6, ... so on
            ]

    }

2 - 第二个设计:集合名称 - activity_stream_fanout


    {
    _id:'activ_fanout_123',
    personId:person3,
    activities:[
    {
     _id:'activ123',
     actor:{
            id:person1
            },
    verb:'follow',
    object:{
            objecttype:'person',
            id:'person2'
            },
    updatedon:Date(),
    }

    ],[
    //activity feed 2
    ]

    }


3 - 这种方法是将活动项目存储在一个集合中,将消费者存储在另一个集合中。在活动中,您可能有一个文档:


    { _id: "123",
      actor: { person: "UserABC" },
      verb: "follow",
      object: { person: "someone_else" },
      updatedOn: Date(...)

    } 

然后,对于粉丝,我会收到以下“通知”文件:


    { activityId: "123", consumer: "someguy", updatedOn: Date(...) }
    { activityId: "123", consumer: "otherguy", updatedOn: Date(...) }
    { activityId: "123", consumer: "thirdguy", updatedOn: Date(...) } 

非常感谢您的回答。

2 个答案:

答案 0 :(得分:20)

我会选择以下结构:

  1. 对发生的所有操作使用一个集合,Actions

  2. 使用其他收藏集来跟踪谁,Subscribers

  3. 对某个用户的新闻Feed使用第三个集合Newsfeed,从Actions集合中展开项目。

  4. Newsfeed集合将由异步处理新Actions的工作进程填充。因此,新闻源不会实时填充。我不同意Geert-Jan,因为实时很重要;我相信大多数用户并不关心大多数(并非所有)应用程序中的一分钟延迟(实时,我会选择完全不同的架构)。

    如果您的consumers数量非常大,那么扇出可能需要一段时间,这是真的。另一方面,将消费者权利放入对象中也不会对非常大的跟随者计数起作用,并且会产生占用大量索引空间的过大对象。

    然而,最重要的是,扇出设计非常更灵活并且允许相关性评分,过滤等。我刚刚写了一篇关于news feed schema design with MongoDB的博客文章,我在那里解释更详细的一些灵活性。

    说到灵活性,我会小心那个activitystrea.ms规范。作为不同提供者之间互操作的规范似乎有意义,但我不会将所有冗长的信息存储在我的数据库中,只要您不打算从各种应用程序聚合活动。

答案 1 :(得分:1)

我相信您应该查看您的访问模式:您可能对此数据执行的查询最多等等。

对我来说,需要最快的用例是能够将某个活动推送到每个“活动消费者”的“墙”(以fb为单位),并在活动进入时立即执行。

从这个角度来看(我没有多想过)我会选择1,因为2.似乎在处理它们之前为某个用户批量活动?因此,如果没有“立即”需要更新。此外,对于这个用例,我没有看到3.超过1的优势。

1上的一些增强功能?问问自己是否真的需要为每项活动定义一系列消费者的灵活性。是否真的需要在这种细粒度范围内指定它?相反,不会引用'演员'的'朋友'就足够了? (从长远来看,这会占用很多空间,因为当消费者通常在数百(?)范围内时,我发现每个活动的消费者数组是整个消息的主要部分。

有点相关的说明:根据您希望如何为这些活动流实现实时通知,可能值得一看Pusher - http://pusher.com/和类似的解决方案。

HTH