使用 NoSQL DB 跟踪用户时间戳数据的 DB 最佳实践(使用 firebase)

Posted

技术标签:

【中文标题】使用 NoSQL DB 跟踪用户时间戳数据的 DB 最佳实践(使用 firebase)【英文标题】:DB Best Practice to track user timestamp data with NoSQL DB (using firebase) 【发布时间】:2021-12-14 20:52:13 【问题描述】:

我有几个我的用户使用的应用程序,我想跟踪他们对 API 限制和每周电子邮件的使用情况。我正在使用 Firebase 实时 NoSQL 数据库。

当一个用户一天可以使用应用程序 100 次而其他用户根本不能使用时,我正在努力寻找用于跟踪使用情况的 NoSQL 数据库设置的最佳实践。我知道我需要保存时间戳,但我不确定推荐的实际设置。

选项 1:

<user_id>/<app_name>/<day_integer> 并保存一个 timestamp 数组。要获得整个月的使用量,我想我必须提出 30 个请求。

选项 2:

<user_id>/usage/<day_integer> 并使用使用计数(1、2、100 等)保存或更新密钥 app_name。要获得整个月的使用量,我想我需要提出 30 个请求。

选项 3:

<user_id>/usage 并使用 app_nametimestamp 值保存对象。我会有大量的对象,这意味着我必须进行大量的数据传输和过滤。

我只需要时间戳来构建使用图表。我找不到任何关于使用跟踪的数据库架构最佳实践的文章。有人对最佳做法有任何见解吗?

【问题讨论】:

【参考方案1】:

老实说,选项之间的差异很小,最佳选项取决于您的用例。


在所有三种情况下,您都可以通过一次操作获取用户在某天范围内的应用使用情况。在前两种情况下,应该是firebase.database().ref(uid).child(appNameOrUsage).orderByKey().startAt(firstKeyToReturn).limitToFirst(30)。在第三种情况下需要firebase.database().ref(uid).child("usage").orderByChild("timestamp").startAt(firstTimeStampOfMonth).endAfter(lastTimestampOfMonth)

即使您需要多个请求,也不会像您想象的那么慢,因为 Firebase 通过单个套接字连接对请求进行管道传输,如下所述:Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly


在 NoSQL 数据库中,通常最好按照屏幕上显示的数据进行存储。由于您似乎想显示每月的使用情况,我实际上建议(也)存储每月的汇总使用情况,以及每个应用每月的使用情况。

如果您具有 SQL 背景,存储重复数据可能会违反直觉,但实际上在 NoSQL 领域中很常见 - 这通常是这些数据库在读取操作方面扩展得如此之好的主要原因。

所以我可能会在这里存储你可能想要的所有聚合,所以:

所有时间的每位用户 每个用户每个月 每用户每所有时间 每个用户每个应用每个月 所有时间的所有用户 每个月的所有用户 等

通过这种方式,写入逻辑变得更加复杂,但读取图表数据变得非常简单。这是 NoSQL 数据库中的另一种常见模式。


最后:Firebase 实时数据库与大多数 NoSQL 数据库一样,不太适合执行即席查询。如果这是您需要的,请考虑为该用例提供更好的解决方案,例如 BigQuery,如果数据集可能变得任意大。

【讨论】:

嘿弗兰克,再次感谢,一个简单的问题,我有成千上万的用户,每天多次记录使用情况(目前使用 redis 进行跟踪)。考虑到未来的增长,Firebase RT 数据库是一个糟糕的选择吗?尽管我的对象又小又简单,但随着数据库大小的增长,我已经看到了对其性能的担忧。 您存储的数据大小几乎无关紧要。重要的是您如何读取数据,以及您读取了多少数据。如果您进行了足够的非规范化,那么每次读取几乎都是一个“从磁盘获取特定数据”的操作,可以很好地扩展。

以上是关于使用 NoSQL DB 跟踪用户时间戳数据的 DB 最佳实践(使用 firebase)的主要内容,如果未能解决你的问题,请参考以下文章

europass db 结构关系或 noSql

如何使用 Spring JDBC Framework 将“null”时间戳插入 DB2 数据库

DB - MongoDB

从 Mapr DB 表中推断为 InvalidType 的 Spark 数据帧时间戳列

在 DB2 中获取没有时间戳的日期

如何编写SQL查询以基于时间戳从DB获取数据