9

我一直想知道在各种情况下最大查询效率的理想文档结构,我想问一个。我真的不知道在这种特定情况下 MongoDB 在内存中的行为方式。让我给你一个假设的场景。

想象一个 Twitter 风格的追随者和追随者系统。经过公认的粗略一瞥,主要选项似乎是:

  1. 在每个用户文档中,一个“关注者”数组包含对他们关注的其他用户的所有文档的引用。通过在其他用户的“user.followers”数组中找到我们当前的用户来找到关注者。主要缺点似乎是 Followee 搜索的潜在查询开销。此外,对于专门针对“user.followers”内容的查询,MongoDB 是只访问用户文档中的必填字段,还是找到整个用户文档,然后从那里查找必填字段值,这是缓存/以这样一种方式存储,即对大型用户群的查询将需要更多的内存?

  2. 在每个用户文档中,存储“followers”和“followees”,以便更快地访问每个用户文档。这显然具有重复数据的缺点,因为用户 A 跟随用户 B 的条目存在于相应字段的两个用户文档中,并且从 from 中删除需要在另一个中匹配删除。从技术上讲,这可能是考虑将简单删除的潜在故障点数加倍。并且当删除发生时,MongoDB 是否仍然遭受我所听到的对它的内存存储数据的“瑞士奶酪”的影响,因此从 2 个字段而不是 1 个字段中删除会使内存漏洞问题的影响加倍?

  3. 用于存储用户关注者的单独集合,以与 1 中的用户文档类似的方式进行查询,除了显然唯一被访问的数据是关注者,因此如果用户文档包含与每个用户相关的大量其他数据,我们避免访问该数据。虽然这似乎有点关系数据库的感觉,虽然我知道这并不总是一种糟糕的方法,但显然如果提到的其他方法之一(或我没有考虑过的方法)在 Mongo 的架构下更好,我很想学习!

如果有人对此有任何想法,或者想告诉我我在某个地方错过了一个非常相关且明显的文档页面,或者甚至想告诉我我只是愚蠢(想解释一下原因,请; ) ) 我很想收到你的来信!

4

2 回答 2

8

这是一个经典的追随者问题,没有一个答案。查看此链接:

mongo db design of following and feeds,我应该在哪里嵌入?

实际上,如果 MongoDB 和 SQL 服务器是您唯一的选择,那么这种情况非常适合关系模式。但这是一种特殊类型的关系问题,其中你有一个双向关系。这可能可以通过图形数据库更好地处理:http:

//forum.kohanaframework.org/discussion/10130/followers-and-following-database-design-like-twitter/p1

问题是,您可以保留关注者或用户文档中的关注者,但不能同时关注,以避免双重删除问题。因此,如果您必须坚持使用 MongoDB,那么一种出路可能是……(假设人们不关注/取消关注任何经常),

只保留文档中的关注者,因为当我查看我的个人资料时,我会对我关注的人感兴趣..(这就是我关注他们的原因,对吧?)..然后做像这样的查询:

db.Users.find({ user_id : { $in : followees })

这将告诉谁都在关注我(比如我的 id 是'user_id')。

我不建议反过来的另一个原因是.. 最多可以关注 30-40 人,因此存储 30-40 个关注者的用户文档应该可以与存储数千个关注者的用户文档相比!使用文档中的跟随者方法,您将获得大致均匀大小的用户文档。在文档中的跟随者方法中,您将获得一些非常小但也非常庞大的文档。并且根据您输入的关注者数据的数量(如果有,除了 follower_id),您可能需要注意文档大小限制。

于 2012-07-16T20:18:17.150 回答
2

鉴于它是多对多关系,选项(2)对我来说看起来不错。至于匹配删除,这通常不是问题,只要您在两个文档之间有某种协调机制即可。

碎片通常取决于应用程序的访问模式,并且通常是大多数数据系统的问题。为了避免内部碎片,对 mongo 进行了一些重大更改。此外,如果发生碎片,还有离线压缩替代方案可以修复碎片。

于 2012-07-16T20:04:52.323 回答