我见过很多关于如何与MongoDB建立多对多关系的帖子,但没有一个提到规模。例如这些帖子:
MongoDB Many-to-Many Association
How to organise a many to many relationship in MongoDB
我可以通过这种设置看到的问题是MongoDB的16MB文档限制。假设我有user
s,group
和post
s。 post
有一个关联的group
和许多user
可以喜欢它。 group
中有post
个user
个,其中有许多user
可以跟随它。 post
可以有很多人喜欢group
,并且可以关注多个user:
user_id
username
post:
post_id
group_id
message
group:
group_id
name
post_likes:
post_id
liked_user_id
group_followers:
group_id
follower_user_id
。如果我用关系数据库构建它,我会这样设置:
group
理论上,post
可以有user
个post
,user
个user
,post
可以拥有无限数量的group
<div class="parent">
<div class="child">...</div>
<div class="child">...</div>
...
</div>
如果在SQL查询中正确完成分页,则 .parent{
margin-right: -2%; /* to compensate for the unwanted margin of what ends up being the right-most element */
}
.child{
display: inline-block;
width: 23% /* I want 4 columns, so it'll be a little less than 25%, right? */
margin-right: 2% /* So width + margin-right percent add up to 25% */
margin-bottom: ? /* Can't say 2% because it's NOT 2% of the parent container's width */
height: 100px; /* constant value */
}
可以拥有无限数量的受欢迎write.csv(cats, "cats_with_numbers.csv", row.names=FALSE)
和std::string type;
TYPE get_type(std::string) { ... }
get_type(type) new_variable();
s。
如何设置MongoDB的架构以便实现这种扩展?
答案 0 :(得分:9)
这是一个很好的问题,它说明了overemebedding的问题以及如何处理它。
让我们坚持用户喜欢帖子的例子,这是一个简单的例子。其他关系必须相应处理。
你绝对正确的是,将这些内容存储在帖子中迟早会导致非常受欢迎的帖子达到大小限制的问题。
所以你正确地回过头来创建一个post_likes
集合。为什么我这称呼为正确?因为它符合您的使用案例以及功能和非功能要求!
post_id
和liked_user_id
上的唯一索引)并使用(用户和帖子都是已知的,因此添加like是一个简单的插入或更可能是UPSERT)但是我会稍微扩展一下这个集合,以防止对频繁使用的某些用例进行不必要的查询。
我们假设现在无法更改帖子标题和用户名。在这种情况下,以下数据模型可能更有意义
{
_id: new ObjectId(),
"post_id": someValue,
"post_title": "Cool thing",
"liked_user_id": someUserId,
"user_name": "JoeCool"
}
现在假设您要显示喜欢帖子的所有用户的用户名。使用上面的模型,这将是一个相当快速的查询:
db.post_likes.find(
{"postId":someValue},
{_id:0,user_name:1}
)
只存储了ID,这个相当常见的任务至少需要两个查询,并且 - 考虑到约束,可能会有无数个类似的帖子 - 可能巨大内存消耗(你需要将用户ID存储在RAM中。
当然,这会导致一些冗余,但即使数百万人喜欢帖子,我们只谈论几兆字节的相对便宜(且易于扩展)的磁盘空间,同时获得很多性能< / strong>在用户体验方面。
现在有了这样的事情:即使用户名和帖子标题可能会发生变化,您也只需进行多次更新:
db.post_likes.update(
{"post_id":someId},
{ $set:{ "post_title":newTitle} },
{ multi: true}
)
您正在进行交易,需要一段时间才能做一些非常罕见的事情,例如更改用户名或帖子,以便极其频繁地发生用例。
请记住,MongoDB是面向文档的数据库。因此,请记录您感兴趣的事件,并使用未来查询所需的值并相应地对数据建模。
答案 1 :(得分:0)
如果您只是在覆盖集合数组中存储关系的ID,那么在单个文档中不应该有太多问题。可以使用GridFS,但这通常更适用于文件,音乐,视频等媒体,使用GridFS会使更新变得痛苦