3

我在一个社交网络项目中工作,建议的数据库是 MongoDB。

我之前从事过各种项目,并在关系数据库系统中设计过数据库,但因为我是 NoSQL db (MongoDB) 的新手。我被设计的东西困住了。

考虑下面的例子,

1)应用程序将有用户和朋友表来保存用户和用户的朋友的数据。

现在,下面的设计是否正确?

用户:

_id       username password other_fields
----------------------------------------
2gsyexej2 balan    adsfasf  ..

用户朋友:

_id user_id friends
--------------------
1  2gsyexej2 friends
               - 0 
                 - friend_user_id = asdfdf23adfsasdf
               - 1
                  - friend_user_id = efex89sdfsw0dfssf
                        etc., 

在上述模型中,我使用了“手动参考”,从 users 表中获取用户 ID,并将其用作 user_friends 表中的参考。

这种方法正确吗?如果没有,请提出更好的方法。

谢谢,

巴兰

4

2 回答 2

5

一位用户有 30 000 000 个朋友。

严重地?新浪微博中文版推特上最大的追随者,人均追随者数量使Facebook和Twitter相形见绌,单人约2000万。然而,这种情况很少见。

话虽如此,将根文档中的朋友关系作为文档(http://docs.mongodb.org/manual/core/data-modeling/)和@jorscas 建议的做法根本不明智。

我可以很容易地想象,随着用户在网站上花费更多时间访问更多朋友关系,文档会以持续快速的速度增长。这会很糟糕,有几个原因,一个是 MongoDB 范围内的空间碎片,两个是因为快速增长的文档可能需要在磁盘上移动,这本身就是一个缓慢而密集的操作。还有更多的原因,但这已经足够了。

您还必须考虑 16meg 的限制,即使 8,000 个连接也会达到该限制。

所以我已经说不要嵌入。你知道在关系模型中设计这个的方式吗?我会这样做,在需要时去规范化,同时规范用户之间的关系。

于 2013-01-16T15:55:16.047 回答
1

为了在 mongodb 中表示用户之间的关系,最自然的方式是在单个用户的集合中使用引用,如下所示:

{
 _id: ObjectId("5099803df3f4948bd2f98391"),
 username: "balan",
 password: "adsafs",
 ...
 other fields
 ...
 friends: [ ObjectId("5099803df3f4948bd2f2334445"), ..., ... ],
}

考虑到朋友的数量很大并且sharding需要的情况下,以前的结构可能很难找到合适的shard key. 在这种情况下,我会使用一个单独的朋友对集合:

{
  _id: ObjectId("..."),
  user_id: ObjectId("..."),
  friend_id: ObjectId("...")
}
于 2013-01-16T13:59:20.777 回答