对于Facebook类型的社交网络应用程序,需要高性能的数据库结构才能将数据存储在Firebase(NoSQL)中。
要存储的数据:
- Userinfo (name, email etc)
- Friends
- Posts
- Comments on posts.
在查询性能(如果数据库变得庞大)的以下两个数据库结构之间,我感到困惑。
(参考:C_xxx是Collection,D_xxx是document)
结构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 /)
由于整个数据库都在一个集合中,因此可伸缩性不好吗?
结构2:
划分的DB->更好的可伸缩性?
分开的DB->更好的性能?
更少的嵌套->更好的性能?
一个帖子下的所有帖子->查询缓慢?
或者,如果您可以提出更好的模型,那也很好。
答案 0 :(得分:3)
在Firebase中,经验法则是将单独的实体类型保留在单独的分支中。这尤其重要,因为:
例如,在您的第一个数据结构中,要加载朋友列表,您将必须加载所有朋友的所有帖子,以及所有这些帖子上的所有评论。如果您只想显示朋友姓名列表,那将比严格需要的数据多得多。
在您的第二个数据结构中,您将近一步。现在,您可以先加载朋友的姓名,然后加载他们的帖子。
但是即使在这种结构中,您也会遇到相同的问题。如果要显示一个朋友(或所有朋友)的帖子标题列表,则必须加载整个帖子和所有评论。这再次是比显示职位列表所需的数据更多的方式。因此,您当然也希望将评论存储在单独的顶级列表中,并使用帖子的相同键来标识和分组评论。
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
现在,如果要显示帖子及其评论,则必须阅读两个节点。如果对多个帖子执行此操作,则最终将产生大量读取,从而实际上执行了与SQL JOIN
等效的NoSQL。这是很正常的事情,它本质上是一个客户端联接,并且它的速度不如您想象的那么慢,因为Firebase pipelines the requests。
有关这种数据建模的更多介绍,我建议:
以下问题的答案: