对于Facebook类型的社交网络应用程序,需要一个高性能的数据库结构,以便在Firebase(Cloud ) (NoSQL)中存储数据。
待储存的数据:
- Userinfo (name, email etc)
- Friends
- Posts
- Comments on posts.我对以下两种关于查询性能的DB结构感到困惑(如果数据库变得庞大)。
(参考文献: C_xxx是集合,D_xxx是文档)
结构1
C_AllData
- D_UserID-1
name: xxxx,
email: yyy,
friends: [UserID-3, UserID-4]
- C_Posts
- D_PostId-1
Text: hhh
Date: zzz
- C_Comments
- D_CommentId-1
UserID: 3
Text: kkk
- D_CommentId-2
UserID: 4
Text: kkk
- D_PostId-2
Text: hhh
Date: zzz
- C_Comments
- D_CommentId-3
UserID: 3
Text: kkk
- D_CommentId-4
UserID: 4
Text: kkk
- D_UserID-2
name: xxxx,
email: yyy
friends: [UserID-5, UserID-7]
- C_Posts
- D_PostId-3
Text: hhh
Date: zzz
- C_Comments
- D_CommentId-5
UserID: 5
Text: kkk
- D_CommentId-6
UserID: 7
Text: kkk结构2
C_AllUsers
- D_UserID-1
name: xxxx,
email: yyy
friends: [UserID-3, UserID-4]
- D_UserID-2
name: xxxx,
email: yyy
friends: [UserID-5, UserID-7]
C_AllPosts
- D_PostId-1
UserID: 1
Text: hhh
Date: zzz
- C_Comments
- D_CommentId-1
UserID: 3
Text: kkk
- D_CommentId-2
UserID: 4
Text: kkk
- D_PostId-3
UserID: 2
Text: hhh
Date: zzz
- C_Comments
- D_CommentId-5
UserID: 5
Text: kkk
- D_CommentId-6
UserID: 7
Text: kkk我的问题是,这两种方法的优缺点是什么?
以下是我能想到的一些问题,如果我错了,请纠正我。
结构1 :
获取给定用户的所有帖子,在结构1中更快吗?因为我们指向的是确切的集合( AllData/{UserID}/Posts/ )
既然整个DB都在一个集合下,可伸缩性就不好吗?
结构2 :
分割DB ->更好的可扩展性?
分割DB ->性能更好吗?
嵌套较少的->性能更好?
AllPosts在一个集合下->慢速查询?
或者,如果你能提出一个更好的模型,那也会很棒。
发布于 2018-09-22 13:25:05
在Firebase中,经验法则是将不同的实体类型保持在不同的分支中。这一点特别重要,因为:
(注:这里的firebase是实时数据库)
例如,在第一个数据结构中,要加载朋友列表,您必须加载所有朋友的所有帖子,以及所有这些帖子上的所有评论。这比严格需要的数据要多得多,如果你只想显示一个朋友的名字列表的话。
在你的第二种数据结构中,你离我们更近了一步。因为现在你可以先加载朋友的名字,然后加载他们的帖子。
但即使在这种结构中,你也有同样的问题。如果您想显示朋友(或所有朋友)的帖子标题列表,则必须加载整个帖子和所有评论。这也比显示帖子标题列表所需的数据要多。因此,您肯定希望将评论存储在一个单独的顶级列表中,使用相同的post键来识别和分组它们。
C_AllPosts
- D_PostId-1
UserID: 1
Text: hhh
Date: zzz
- D_PostId-3
UserID: 2
Text: hhh
Date: zzz
C_AllComments
- D_PostId-1
- D_CommentId-1
UserID: 3
Text: kkk
- D_CommentId-2
UserID: 4
Text: kkk
- D_PostId-3
- D_CommentId-5
UserID: 5
Text: kkk
- D_CommentId-6
UserID: 7
Text: kkk现在,如果您想显示一个post及其注释,则必须读取两个节点。如果您对多个帖子执行此操作,那么最终将需要进行大量的读取,从而在本质上执行与SQL JOIN等效的JOIN。这是非常正常的,它本质上是一个客户端连接,而且它并不像您想象的那么慢,因为消防管线请求。
关于这类数据建模的更多介绍,我建议:
以上问题的答案是:
https://stackoverflow.com/questions/52454891
复制相似问题