对于非常简单的问题(或不是非常),我找不到“最佳”解决方案
拥有经典的数据集:附加到用户的帖子,附加到帖子和用户的评论。
现在我无法决定如何构建方案/类
通常是将user_id存储在注释和内部。
但是当我在页面上发表200条评论时会发生什么?
或者当我在页面上有N个帖子时?
我的意思是它应该是200个额外的数据库请求来显示用户信息(例如名称,头像)
另一个解决方案是将用户数据嵌入到每个评论和每个帖子中。
但首先 - >这是巨大的开销,第二 - >模型系统被破坏(使用mongoalchemy),第三个>用户可以更改他的信息(如头像)。然后是什么?据我所知,对大量评论或帖子的更新操作不是简单的操作......
你会建议什么?每页200个请求到mongodb是否正常(必须以性能为目标)?
或者我可能只是错过了一些东西......
答案 0 :(得分:3)
您可以使用$in
- 查询来避免数百个请求的N+1
问题。考虑一下:
Post {
PosterId: ObjectId
Text: string
Comments: [ObjectId, ObjectId, ...] // option 1
}
Comment {
PostId: ObjectId // option 2 (better)
Created: dateTime,
AuthorName: string,
AuthorId: ObjectId,
Text: string
}
现在,您可以使用$in
查询找到帖子评论,还可以轻松找到特定作者发表的所有评论。
当然,您也可以将注释存储为post中的嵌入式数组,并在获取注释时对用户信息执行$in
查询。这样,您不需要对用户名进行反规范化,仍然不需要数百个查询。
如果您选择对用户名进行非规范化,则必须更新该用户在用户更改时所做的所有评论,例如:他的名字。另一方面,如果这种操作不经常发生,那应该不是什么大问题。或者根据您的要求,存储用户在评论时所拥有的名称甚至更好。
嵌入的一般问题是different writers will write to the same object,因此您必须使用atomic modifiers(例如$push
)。这有时候很难用于地图制作者(虽然我不知道mongoalchemy),而且通常不那么灵活。
答案 1 :(得分:1)
我对mongodb的处理方法是将用户ID嵌入到注释中(这是“post”文档结构的一部分)。
提供更好表现的三个简单提示:
1)确保确保user_id上的索引
2)使用注释分页方法来避免查询数据库的200次
3)缓存是你的朋友
答案 2 :(得分:0)
您可以缓存用户对象,这样您就不必每次都查询数据库。
我喜欢将用户数据嵌入到每个帖子中的想法,但是你必须考虑当用户的个人资料更新时会发生什么?必须确保没有错过帖子。
我建议您首先浏览一下mongo建议您如何处理模式。
通常,对于实体之间的“包含”关系, 应该选择嵌入。不使用链接时使用链接会导致 重复数据。
答案 3 :(得分:0)
MongoDB文档中有一个非常好的用例:http://docs.mongodb.org/manual/use-cases/storing-comments/ 方便地,它也用Python编写: - )