MongoDB数据库模式设计



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

1 - 以这种模式存储所有朋友/关注者的每个活动:

   {     _id:"激活123",     演员:{            编号:人1            },    动词:"跟随",    对象:{            对象类型:"人",            ID:"人2"            },    updatedon:Date(),    消费者:[            人3, 人4, 人5, 人6, ...等等            ]    }

2 - 第二种设计:系列名称 - activity_stream_fanout

   {    _id:"activ_fanout_123",    人 ID:人3,    活动:[    {     _id:"激活123",     演员:{            编号:人1            },    动词:"跟随",    对象:{            对象类型:"人",            ID:"人2"            },    updatedon:Date(),    }    ],[    活动源 2    ]    }

3 - 此方法是将活动项存储在一个集合中,将使用者存储在另一个集合中。在活动中,您可能有一个文档,例如:

   { _id: "123",      演员: { 人: "用户ABC" },      动词:"跟随",      对象: { 人: "someone_else" },      更新日期: 日期(...    }

然后,对于关注者,我将拥有以下"通知"文档:

   { activityId: "123", consumer: "someguy", updateOn: Date(...) }    { activityId: "123", consumer: "otherguy", updateOn: Date(...) }    { activityId: "123", consumer: "Thirdguy", updateOn: Date(...) }

非常感谢您的回答。

我会使用以下结构:

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

  2. 使用另一个集合来表示谁关注谁,Subscribers

  3. 使用第三个集合,Newsfeed对于特定用户的新闻源,项目将从Actions集合中扇出。

Newsfeed集合将由异步处理新Actions的工作进程填充。因此,新闻源不会实时填充。我不同意Geert-Jan的观点,即实时很重要;我相信大多数用户根本不关心大多数(不是全部)应用程序中哪怕一分钟的延迟(对于实时,我会选择完全不同的架构)。

如果您有非常多的consumers,扇出可能需要一段时间,确实如此。另一方面,将消费者直接放入对象中也不适用于非常大的关注者数量,并且它将创建占用大量索引空间的过大对象。

然而,最重要的是,扇出设计更加灵活,允许相关性评分、过滤等。我最近刚刚写了一篇关于使用MongoDB进行新闻提要模式设计的博客文章,其中我更详细地解释了其中的一些灵活性。

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

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

对我来说,需要最快的用例是能够将某个活动推送到每个"活动消费者"的"墙"(以fb术语表示),并在活动进入时立即进行。

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

1 的一些增强功能?问问自己,你是否真的需要为每个活动定义一组消费者的灵活性。真的有必要在这个细粒度的规模上指定这一点吗?相反,提及"演员"的"朋友"还不够吗?(从长远来看,这将占用大量空间,因为我认为消费者数组是每个活动的整个消息的大部分,而消费者通常范围为数百(?)。

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

相关内容

  • 没有找到相关文章

最新更新