Firebase 实时数据库定价与查询

Posted

技术标签:

【中文标题】Firebase 实时数据库定价与查询【英文标题】:Firebase Realtime Database Pricing with Query 【发布时间】:2020-03-15 13:19:12 【问题描述】:

我对 Firebase 数据库定价有疑问。我的数据库的排行榜中有大约 400,000 行,但在我的应用程序中,我只想加载最后 500 行,所以我的问题是我会在运行查询时为加载的 500 行付费,还是会为所有行付费400,000 行。

实时数据库每存储 GB 收费 5 美元,下载每 GB 收费 1 美元。我用 Firestore 进行了计算,发现如果我为 500 行而不是 400,000 行收费,实时数据库会便宜得多。

我搜索了所有文档,但没有找到任何关于查询的信息:https://firebase.google.com/pricing https://firebase.google.com/docs/database/usage/billing

有人能告诉我是只对我的集合中的 500 行还是对集合中的所有数据收费,是否有办法只对 500 行收费,可能有安全规则?

这是我的查询代码:

let queryRef = ref.child("Leaderboard").queryOrdered(byChild: "totalStars").queryLimited(toLast: 500)

数据库的外观。 (它将有大约 500,000 个与这些相同的孩子,每天加载 200,000 个,但我只想在我加载的前 500 个中定价,而不是每次用户加载排行榜时的全部 500,000 个,这可能吗?)

【问题讨论】:

【参考方案1】:

您只需为与查询结果相对应的Firestore文档数量付费(而不是集合中的文档数量)。

因此在您的情况下最多读取 500 次,因为您会将查询限制为 500 个文档。


另一方面,请注意实时数据库查询并不浅(而 Firestore 查询是),因此如果您查询 JSON 节点,您将获得该节点下的整个树 .

【讨论】:

是的,我知道这适用于 Firestore,但我要求的是实时数据库。 因此,如果我查询最后 500 个或不查询,我仍然会为加载的整个数据付费。在这种情况下你会推荐什么,因为如果我使用 Firestore 每天 200,000 个请求来处理 500 行,我将不得不每天支付 60 美元,你认为实时数据库是更好的选择吗? 您确实必须进行数学计算,考虑到构成定价的不同元素(一方面是存储、网络出口、文档读取,另一方面是 GB 存储和 GB 下载)。跨度> @jmapps9 这是一个很好的答案!让我补充一个想法;您问题中的查询是针对 RTDB 的。如果这是一个选项,我会建议 RTDB 和非规范化你的数据;保留一个单独的 leaderboard_stars 节点,该节点仅包含对排行榜中内容的引用,或者可能是一个非常浅的引用节点、名称和星数,当您需要加载最后 500 个时,请改用该节点可能包含更多数据的排行榜节点。在 RTDB 中加载 500 个非常浅的节点是极少量的数据和非常低的成本。 @jmapps9 将获得的星星数量也保存在一个单独的浅节点中。假设用户是 Firebase 用户,将子节点存储为一个键:uid: number of stars 的值对,或者可能是一个浅键:具有两个子节点 uid: player nameuid: number of stars 的值对 复制数据在 NoSQL 数据库中非常常见 -这是使它们如此快速和高效的部分原因,因为磁盘空间很便宜。然后你可以用很少的数据排序并得到最后的 500 个。【参考方案2】:

Renaud 的回答是正确的,但让我补充一些额外的信息并重申:

使用 Firebase 实时数据库下载您需要付费 下载的是什么,而不是您要查询的节点数。

因此,关键是减少您正在下载的数据量。您的节点已经很浅了,但是可以节省大量资金,因为在您当前的结构中,节点键(用户 uid)在节点内被复制为子节点,这不是必需的。

您始终可以使用snapshot.key 获取节点密钥并删除该子节点。所以它看起来像

uid
   fullName: "Logan Paul"
   stars: 40

另外,我认为你的计算有点偏差。看起来每个节点大约有 100 个字节的数据,并且 Firebase 字符串是 UTF-8 编码的,所以如果你每天为每个用户下载 500 个节点并且你有 200,000 个用户,那么每天大约 38Gb(作为二进制)。

大约 400 字节 * 500 个节点 * 200,000 个用户 * 每 Gb 0.000000000931322574615479 字节 = 38Gb

如果我的数学计算正确的话,每天大约 38 美元。

【讨论】:

我根据以下内容进行了计算: 1. 如果包含 500,000 个文档,则整个排行榜的每个文档为(146 字节),则总数为 0.073 GB 2. 如果 200,000 个用户加载 0.073 GB每天加载 14,600 GB 的数据,因此每天大约 14,600 美元。我觉得有问题? 有没有一种方法可以为我提供最便宜的选择,即使这意味着使用 Firestore。在我的情况下,你会推荐什么? 因为根据 Renaud 的回答,我将为数据库中的所有节点付费,而不仅仅是使用实时数据库时加载的前 500 个节点。 @jmapps9 见上面我的 cmets。 @jmapps9 Renaud 在他的回答中所说的是,您需要为 与您的查询结果相对应的 Firestore 文档数付费 - 注意:查询结果。如果您在 Firestore 中存储了 100 万个文档,并且您的查询返回 10,则您需要为 10 个付费。在 RTDB 中,您需要为返回的字节数付费,因此您希望专注于返回最少的字节数。如果返回 500 个节点,每个节点是 400 字节,每天 200,000 个,大约是 38 美元。请参阅我的答案中的 RTDB 结构和计算。

以上是关于Firebase 实时数据库定价与查询的主要内容,如果未能解决你的问题,请参考以下文章

将 async/await (Swift 5.5) 与 firebase 实时数据库一起使用

firebase 9 查询实时数据库的关键

将 Firebase 实时数据库与 SwiftUI 列表一起使用 - 清除列表

Flutter:Firebase 实时数据库 orderByChild 对查询结果没有影响

Firebase 实时数据库在查询之间按单词搜索?

Firebase实时数据库数组查询问题[重复]