首页 > 解决方案 > 有一种方法可以减少在 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 之间的个人资料和对话(以获取他们的头像为例),我需要:

  1. 检查他们的朋友是否
  2. 如果是,获取 0000 的消息
  3. 获取8888的消息
  4. 获取 0000 个人资料
  5. 获取8888个人资料

如果我想要 0000 的所有对话列表,我需要这样做:

  1. 检查所有用户以了解他们是否是朋友
  2. 对于每个朋友,获取个人资料
  3. 对于每个朋友,获取消息列表。

这是非常简单的查询,例如,这似乎比 mysql 更重。

有没有办法不做所有这些查询?我的数据库模式好不好?

感谢帮助。

标签: javascriptreactjsfirebasereact-nativenosql

解决方案


是时候将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 之间的个人资料和对话(以获取他们的头像为例),我需要:

  1. 检查他们的朋友是否
  2. 如果是,获取 0000 的消息
  3. 获取8888的消息
  4. 获取 0000 个人资料
  5. 获取8888个人资料

查询或在message哪里。senderreceiverfollow

如果我想要 0000 的所有对话列表,我需要这样做:

  1. 检查所有用户以了解他们是否是朋友
  2. 对于每个朋友,获取个人资料
  3. 对于每个朋友,获取消息列表。

查询或等于message_senderreceiver'0000'

您可能会遇到的其他用例:

  • 列出姓名和头像的朋友列表。

您可以使用 map 数组follow来存储uid,如果您打算对其进行多项操作nameavatar甚至可以将 follow 作为子集合。

  • 用户更改名称或头像。

与发送的消息数量相比,名称或头像的更改通常不太频繁,并且可能不需要实时更改。如果需要更新所有消息,您可以创建一个云功能来批量更新所有消息

说了这么多,显然是您选择使用 SQL 还是 NoSQL。两者各有优缺点


推荐阅读