【问题标题】:Having quite a lot of issues when write massive record to firebase database将大量记录写入firebase数据库时遇到很多问题
【发布时间】:2017-05-28 03:31:21
【问题描述】:

从我的last question 让我决定将大量数据写入 用于测试目的的 firebase 数据库。

这是结果

  • 1000 条记录:没有什么大事发生,它工作正常。
  • 10000 条记录:来自 firebase 的所有其他读取操作的响应仅在写入操作完成后才返回。
  • 100000 记录:与 10000 记录的结果相同,但花费的时间更长,除非强制关闭应用程序并重新打开它,否则我无法执行任何 Firebase 操作。屏幕开始挂起一段时间可能是因为我在主线程(ios)中执行循环。
  • 100 万条记录:恐怕永远不要尝试。

我需要写这么多数据的原因是因为我以前使用 SQL 构建了一些社交应用程序(android、ios、web),但我认为是时候切换到 firebase 了。通过研究this,我知道了如何在不使用IN 子句的情况下构建用户提要。数据结构是这样的

users
  user1
    name: bob
  user2
    name: alice
    follows: 
      user1: true

posts
  post1
     author: user1
     text: 'Hi there'

feeds
  user2
    post1: true

例如,如果用户中有 6100 万粉丝,则需要将记录插入到 6100 万 feeds/$uid/。写入操作几乎无法生存 100k。在这个link 上,建议不要在客户端执行此操作,但firebase 的重点是我想在客户端旁边编写它是无止境的。

所以我的问题是有什么有效的方法来实现如何不让这种大规模的写入操作中断其他读取操作?或者有更好的数据建模方法?

我真的需要帮助。我真的很感激,即使只是一个评论。

【问题讨论】:

  • 有点不清楚问题到底是什么。据了解,写入 100 万条记录需要“一段时间”,但更大的问题是为什么您要写入 100 万条记录。从整体上看,如果一个用户有 6100 万粉丝,那么每个粉丝都会观察 feed 节点。如果该用户添加/更新一个提要,每个观察者都会收到一个事件,通知他们该提要 - 所以一个添加或更新就是客户端应用程序发送到 Firebase 的全部内容。我认为您可能希望通过澄清用例来更新您的问题,并请包含代码,以便我们可以看到您实际在做什么。
  • @Jay 好吧,我的错。假设不同的用户有不同的追随者,所以他们的提要会有所不同。如果某人有 6100 万追随者,我需要将他的帖子添加到他的追随者提要中,这将写入 6100 万条记录,所以我可以使用 /feed/userId/postId 进行查询,然后使用 /post/postId 加入它。另一种选择是收听所有当前用户关注的帖子,如果用户关注了数千个用户,这可能是读取操作中的问题。
  • 我认为您可能正在倒退。您应该有一个 /feeds 节点,所有用户都在观察包含感兴趣的特定 uid 的提要。例如,假设 uid_0 希望在提要从 uid_5 发布时得到通知。如果 uid_5 发布新的提要,他们会将其发布到 /feeds/feed_xx/posted_by: uid_5。然后,uid_0 将被通知该提要。没有必要做更多的事情。也许我误解了用例?
  • @Jay 喜欢 twitter 主页。根据推文创建日期,Twitter 提要将拥有所有当前关注帐户和他自己的推文在家庭提要上的人。这就是我为每个提要创建所有用户的原因。无论如何感谢您的回复。
  • 如果您阅读了您在评论中写的内容,所有当前关注帐户的人。这正是我所说的;用户选择关注另一个用户 - 这些用户已将观察者添加到他们想要关注的用户(提要)。当被关注的人在他们的动态中发布内容时,关注者会收到一个事件。

标签: firebase firebase-realtime-database


【解决方案1】:

让我们从一个示例 Firebase 结构开始,它使用观察者和事件来捕获来自特定用户的提要。

我们有一个用户节点,它存储有关所有用户的数据,在这种情况下只是他们的姓名。我们还有一个存储提要的提要节点。在这种情况下,我们也可以将其称为消息,因为我们只是存储用户创建的消息。

users
  uid_0
    name: "Scott"
  uid_1
    name: "Frank"
  uid_2
    name: "Leroy"

feeds
  feed_0
    uid: uid_1
    msg: "some message from uid_1"
  feed_1
    uid: uid_2
    msg: "a message from uid_2"

假设 Scott (uid_0) 想要“订阅”来自 Frank 和 Leroy 的任何供稿。

func addSomeFeeds() {
    self.addFeed(uidFeed: "uid_1")
    self.addFeed(uidFeed: "uid_2")
}

func addFeed(uidFeed: String) {
    let feedsRef = self.ref.child("feeds")
    let feedQuery = feedsRef.queryOrdered(byChild: "uid").queryEqual(toValue: uidFeed)
    feedQuery.observe(.childAdded, with: { snapshot in

        let feedDict = snapshot.value as! [String: Any]
        let msg = feedDict["msg"] as! String
        print(msg)
    }) 
}

和输出

some message from uid_1
a message from uid_2

然后如果 uid_2 添加另一个提要(带有消息)

Feed From uid_2

上述代码在 Scott 的设备上运行,并将观察者附加到 Feeds 节点,该观察者“监视”由 Frank 或 Leroy添加的任何 Feed。

这可以通过 .childChanged 扩展并监视更改,因此,如果提要中有多个“帖子”,则只要在特定提要中更新帖子,Scott 的应用就会收到该提要中的更改通知。

另一种选择是向提要节点添加一个更通用的观察者,而应用程序将收到添加、更改或删除的任何个提要的通知。在这种情况下,当应用收到提要的快照时,只需将其与用户感兴趣的提要数组进行比较,如果与其中一个不匹配,则忽略它,否则,通知用户。

【讨论】:

  • 谢谢兄弟,我想我可以通过学习你的例子来解决我的问题。谢谢你的努力
  • 离开前只有一件事。如果我订阅了数千个提要,这种方法会有效吗?
  • @teckwei 是的,它非常高效和快速!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 2014-08-04
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 2013-06-03
  • 2018-12-13
相关资源
最近更新 更多