javascript - 有一种方法可以减少在 Firebase 中的请求吗?
问题描述
实际上我的 Firestore 收藏是这样的:
user :
|-> 0000 (uid)
|-> avatar : 'url'
|-> name : 'josh'
|-> 1111
|-> avatar : 'url'
|-> name : 'steve'
[...]
follow :
|-> 0000
|-> 1111 : true
|-> 8888 : true
[...]
message :
|-> 0000
|-> 8888
|-> 1264978800 (timestamp)
|-> message = "hello"
|-> 1264978987
|-> message = "How are you"
|-> 8888
|-> 0000
|-> 1264914253
|-> message = "hey dude "
|-> 1264975895
|-> message = "fine and you?"
如果我想获取 0000 和 8888 之间的个人资料和对话(以获取他们的头像为例),我需要:
- 检查他们的朋友是否
- 如果是,获取 0000 的消息
- 获取8888的消息
- 获取 0000 个人资料
- 获取8888个人资料
如果我想要 0000 的所有对话列表,我需要这样做:
- 检查所有用户以了解他们是否是朋友
- 对于每个朋友,获取个人资料
- 对于每个朋友,获取消息列表。
这是非常简单的查询,例如,这似乎比 mysql 更重。
有没有办法不做所有这些查询?我的数据库模式好不好?
感谢帮助。
解决方案
是时候将NoSQL与 Firebase 结合使用了。Firestore 是一个注重性能的实时数据库。您的数据结构适用于 SQL 数据库,而不适用于 NoSQL。
以下是我为此用例提出的数据结构:
user :
|-> 0000 : //uid
|-> id : '0000'
|-> avatar : 'url'
|-> name : 'josh'
|-> follow : ['1111', '8888'] // Array of uid
|-> 1111 : //uid
|-> id : '1111'
|-> avatar : 'url'
|-> name : 'steve'
|-> follow : ['0000'] // Array of uid
[...]
message :
|-> AAAA // message id
|-> id : 'AAAA'
|-> sender
|-> id: '0000'
|-> avatar: 'url'
|-> name: 'josh'
|-> receiver
|-> id: '8888'
|-> avatar: 'url'
|-> name: 'paul'
|-> time : 1264978800 // timestamp
|-> message : "hello"
|-> BBBB // message id
|-> id : 'BBBB'
|-> sender
|-> id: '8888'
|-> avatar: 'url'
|-> name: 'paul'
|-> receiver
|-> id: '0000'
|-> avatar: 'url'
|-> name: 'josh'
|-> time : 1264978800 // timestamp
|-> message : "hey dude"
|-> CCCC // message id
|-> id : 'CCCC'
|-> sender
|-> id: '0000'
|-> avatar: 'url'
|-> name: 'josh'
|-> receiver
|-> id: '8888'
|-> avatar: 'url'
|-> name: 'paul'
|-> time : 1264978800 // timestamp
|-> message : "How are you"
|-> DDDD // message id
|-> id : 'DDDD'
|-> sender
|-> id: '8888'
|-> avatar: 'url'
|-> name: 'paul'
|-> receiver
|-> id: '0000'
|-> avatar: 'url'
|-> name: 'josh'
|-> time : 1264978800 // timestamp
|-> message : "fine and you?"
上述结构是采用 NoSQL 方式设计的。用户的个人资料被多次复制。存在数据复制以提高性能并降低比存储成本高得多的带宽和 CPU 成本。
好处:
- 每个用户都包含有关用户的所有信息
- 每条消息都包含有关消息的所有信息
现在,让我们来看看你的用例:
如果我想获取 0000 和 8888 之间的个人资料和对话(以获取他们的头像为例),我需要:
- 检查他们的朋友是否
- 如果是,获取 0000 的消息
- 获取8888的消息
- 获取 0000 个人资料
- 获取8888个人资料
查询或在message
哪里。sender
receiver
follow
如果我想要 0000 的所有对话列表,我需要这样做:
- 检查所有用户以了解他们是否是朋友
- 对于每个朋友,获取个人资料
- 对于每个朋友,获取消息列表。
查询或等于message
_sender
receiver
'0000'
您可能会遇到的其他用例:
- 列出姓名和头像的朋友列表。
您可以使用 map 数组follow
来存储uid
,如果您打算对其进行多项操作name
,avatar
甚至可以将 follow 作为子集合。
- 用户更改名称或头像。
与发送的消息数量相比,名称或头像的更改通常不太频繁,并且可能不需要实时更改。如果需要更新所有消息,您可以创建一个云功能来批量更新所有消息
说了这么多,显然是您选择使用 SQL 还是 NoSQL。两者各有优缺点
推荐阅读
- java - 光标没有给出任何答案
- android - 为什么我的底部导航视图只包含第一项的文本?
- python - 拟合函数中引发的错误:ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()
- cqrs - 使用 NEventStore 实现乐观并发的正确方法
- android - Firebase 云消息不会向所有活跃用户发送通知
- security - 是否有任何具有 Android 功能的单板计算机 (SBC) 并为已安装的软件提供复制保护?
- c# - 如何使用 IEnumerable 对 @Html.DisplayNameFor 进行空检查 - C# & ASP.NET MVC
- c# - 如何使用 FOR 循环打印一维数组元素
- c++ - 从 Dll 调用具有偏移地址的成员函数
- oop - 我们可以在父类和子类中有相同的抽象方法吗