【问题标题】:Swift Firebase "Fan Out" Technique vs queryLimited EfficiencySwift Firebase“扇出”技术与 queryLimited Efficiency
【发布时间】:2021-07-17 05:13:16
【问题描述】:

我的应用中有一个群聊功能,其消息节点的结构如下所示。目前,它不使用扇出技术。它只列出组名下的所有消息,例如“组1”

groups: {
    group1: {
      -MEt4K5xhsYL33anhXpP: {
          fromUid: "diidssm......."
          userImage: "https://firebasestorage..."
          text: "hello"
          date: 1617919946
          emojis: {
              "heart": 2
              "like": 1
          }
      }
      -MEt8BLP2yMEUMPbG2zV: {
          ...
      }
      -MF-Grpl8Jchxpbn2mxH: {
          ...
      }
      -MF-OUjWXsFh7lBPosMf: {
          ...
      }
    }
}

我首先观察最近的 40 条消息,然后观察是否添加了新的孩子

ref = Database.database().reference().child("groups").child("group1")
ref.queryLimited(toLast: 40).observe(.childAdded, with: { (snapshot) in
    ...
    //add to messages array to load collection view
    //for each message observe emojis and update emojis to reflect changes e.g. +1 like

    ref.child("emojis").observe(.value, with: { (snapshot) in
        ...
    })
})

每次用户向上滚动时,我都会使用最后日期(以及安全规则中的日期索引)再加载 40 条消息(并观察每个消息节点下的表情符号子节点)

ref.queryOrdered(byChild: "date").queryEnding(beforeValue: prevdate, childKey: messageId).queryLimited(toLast: 40).observeSingleEvent(of: .value, with: { (snapshot) in

我了解扇出技术用于在每次同步时获取更少的信息。如果我将侦听器附加到 groups/groupname/ 以获取该组的所有消息的列表,我还将询问该节点下每条消息的所有信息。使用扇出方法,我还可以使用来自另一个节点的消息的键来询问最近 40 条消息的消息信息,以及接下来的 40 条消息。

allGroups: {
    group1: {
      -MEt4K5xhsYL33anhXpP: 1
      -MEt8BLP2yMEUMPbG2zV: 1
      -MF-Grpl8Jchxpbn2mxH: 1
      -MF-OUjWXsFh7lBPosMf: 1
    }
}

但是,如果我使用的是 queryLimited(toLast: 40),那么扇出方法是否有益甚至是必要的?这不是解决了“我还会询问该节点下的每条消息的所有信息”的问题吗?

在检查新消息方面,我只是在上面的第一个代码中使用 .childAdded 进行检查(ref.queryLimited(toLast: 40).observe(.childAdded))。根据下面的帖子,queryLimited(toLast: 40) 将同步最后 40 个子节点,并继续同步那些(在添加新节点时删除以前的节点)。

Some questions about keepSynced(true) on a limited query reference

我假设 group1 有 1000 条消息,通过这种方法,我只阅读我需要的 40 条最新消息和接下来的 40 条每个滚动条,因此忽略其他数百条消息。那我为什么要使用扇出技术呢?可能是我不了解有关有限查询的基本知识。

附带问题:我是否应该在每个消息节点下包含对个人资料图像的引用?在云存储和实时数据库存储方面这样做是不是很糟糕?理想情况下会有数百个群聊。

【问题讨论】:

  • 扇出数据可以有多种形式。当您说“扇出技术”时,您能否编辑您的问题以显示您想到的 JSON?
  • 当然。刚刚添加。
  • 我不确定我是否理解这种新数据结构与您问题顶部的数据结构之间的关系。如果您随后以无法通过查询处理的方式加载特定组的数据,而不是其他组的数据,那么拥有这样的组 ID 列表是一个好主意。由于查询对您有用,我不会立即看到对解构数据的需求,但这可能是因为我现在不了解您的所有用例。
  • 成千上万的人从哪里来 - 如果有数千个帖子,那么这些帖子中有成千上万的表情符号观察者。如果 emoji 节点是独立的,那么同一个任务需要一个观察者并加载更少的数据;所以这只是一个设计选择。将参考存储到用户节点中的图像需要额外的读取,因为帖子被读取,然后用户节点从存储中获取图片。另一方面,将 ref 保留在帖子中会减少阅读量,但如果图片发生变化,您必须在每篇帖子中更新它。我会投票给前一个。
  • ref.queryLimited(toLast: 40) 有点不清楚,直到您将大脑围绕它。这实际上是在说“无论查询是什么,限制为最后 40 个”;它不会查询所有内容以获取最后 40 个。因此,如果 40 个“位于顶部”或 40 个“位于末尾”,则性能“相同”;它不是“查看”其他顶级节点。读取性能不会受到显着影响,而且...... Firebase 速度非常快,因此实际上很难制作影响读取性能的东西。 @FrankvanPuffelen 可能想纠正/更新我,但这是我们的测试显示的。

标签: swift firebase performance firebase-realtime-database


【解决方案1】:

这个问题有很多问题,所以我想我会把所有这些都浓缩成一个答案。

问题中“扇出技术”的目的是最大化查询性能。

在这个用例中,查询只返回最后 40 个结果

ref.queryLimited(toLast: 40)

问题中的假设是 Firebase 必须“遍历”这 40 个节点之前的所有节点才能到达 40 个节点,因此会影响性能。 Firebase 的情况并非如此,因此无论是前 40 个还是后 40 个,性能都“相同”。

因此,在这种情况下实际上不需要“扇出”。为清楚起见

扇出是在数据库中复制数据的过程。什么时候 数据是重复的,它消除了慢速连接并增加了读取 性能。

我将从old Firebase Blog 中窃取一个扇出示例。这是一次更新多个节点的扇出,因为它是原子操作,所以要么全部通过,要么全部失败。

let updatedUser = ["name": "Shannon", "username": "shannonrules"]
let ref = Firebase(url: "https://<YOUR-FIREBASE-APP>.firebaseio.com")

let fanoutObject = ["/users/1": updatedUser, 
                    "/usersWhoAreCool/1": updatedUser, 
                    "/usersToGiveFreeStuffTo/1", updatedUser]

ref.updateChildValues(updatedUser) // atomic updating goodness

我还将提供一个指向 Introducing multi-location updates and more 的链接,并建议阅读非规范化主题。

在这个问题中,实际上没有任何数据可以“扇出”,因此它不适用,因为没有尝试加入(从多个节点提取数据)或更新多个节点。

我建议的一项更改是从消息节点中删除表情符号节点。

事实上,每个人都有一个观察者,这导致数以千计的观察者很难管理。我会为那些表情符号创建一个单独的高级节点

emojis
   -MEt4K5xhsYL33anhXpP: //the message id
      "heart": 2  //or however you want to store them
      "like": 1

然后将单个观察者(更容易管理!)添加到表情符号节点。当表情符号发生变化时,一位观察者将通知应用程序它是针对哪条消息的,以及变化是什么。它还将减少读取和总体成本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    相关资源
    最近更新 更多