使用 NoSQL DB 跟踪用户时间戳数据的数据库最佳实践(使用 firebase)
DB Best Practice to track user timestamp data with NoSQL DB (using firebase)
我有几个我的用户使用的应用程序,我想跟踪他们对 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_name
和 timestamp
值的对象。我会有大量对象,这意味着我必须进行大量数据传输和过滤。
我只需要时间戳来构建使用情况图表。我找不到任何关于使用跟踪的数据库架构最佳实践的文章。有没有人对最佳做法有任何见解?
老实说,选项之间的差异很小,最佳选项取决于您的用例。
在所有三种情况下,您都可以通过一次操作获取某个用户在一定天数内对某个应用的使用情况。在前两种情况下,那将是 firebase.database().ref(uid).child(appNameOrUsage).orderByKey().startAt(firstKeyToReturn).limitToFirst(30)
。在第三种情况下,需要 firebase.database().ref(uid).child("usage").orderByChild("timestamp").startAt(firstTimeStampOfMonth).endAfter(lastTimestampOfMonth)
.
即使您需要多个请求,也没有您想象的那么慢,因为 Firebase 通过单个套接字连接对请求进行管道处理,如下所述:
在没有SQL 的数据库中,通常最好按照在屏幕上显示的数据来存储数据。由于您似乎想显示每月的使用情况,我实际上建议(也)存储每月和每个应用每月的汇总使用情况。
如果您来自 SQL 背景,那么存储重复数据可能违反直觉,但实际上在 NoSQL 地区很常见 - 这通常是这些数据库扩展如此之好的主要原因说到读操作。
所以在这里我可能会存储您可能需要的所有聚合,所以:
- 所有时间每个用户
- 每个用户每个月
- 所有时间每个用户
- 每个用户每个应用每月
- 所有时间的所有用户
- 每个月的所有用户
- 等等
这样写入逻辑变得更加复杂,但是读取图表数据变得非常简单。这是 NoSQL 数据库中的另一种常见模式。
最后:Firebase 实时数据库与大多数 NoSQL 数据库一样,不太适合执行临时查询。如果那是您所需要的,请考虑针对用例的更好解决方案,例如如果数据集可能变得任意大,则使用 BigQuery。
我有几个我的用户使用的应用程序,我想跟踪他们对 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_name
和 timestamp
值的对象。我会有大量对象,这意味着我必须进行大量数据传输和过滤。
我只需要时间戳来构建使用情况图表。我找不到任何关于使用跟踪的数据库架构最佳实践的文章。有没有人对最佳做法有任何见解?
老实说,选项之间的差异很小,最佳选项取决于您的用例。
在所有三种情况下,您都可以通过一次操作获取某个用户在一定天数内对某个应用的使用情况。在前两种情况下,那将是 firebase.database().ref(uid).child(appNameOrUsage).orderByKey().startAt(firstKeyToReturn).limitToFirst(30)
。在第三种情况下,需要 firebase.database().ref(uid).child("usage").orderByChild("timestamp").startAt(firstTimeStampOfMonth).endAfter(lastTimestampOfMonth)
.
即使您需要多个请求,也没有您想象的那么慢,因为 Firebase 通过单个套接字连接对请求进行管道处理,如下所述:
在没有SQL 的数据库中,通常最好按照在屏幕上显示的数据来存储数据。由于您似乎想显示每月的使用情况,我实际上建议(也)存储每月和每个应用每月的汇总使用情况。
如果您来自 SQL 背景,那么存储重复数据可能违反直觉,但实际上在 NoSQL 地区很常见 - 这通常是这些数据库扩展如此之好的主要原因说到读操作。
所以在这里我可能会存储您可能需要的所有聚合,所以:
- 所有时间每个用户
- 每个用户每个月
- 所有时间每个用户
- 每个用户每个应用每月
- 所有时间的所有用户
- 每个月的所有用户
- 等等
这样写入逻辑变得更加复杂,但是读取图表数据变得非常简单。这是 NoSQL 数据库中的另一种常见模式。
最后:Firebase 实时数据库与大多数 NoSQL 数据库一样,不太适合执行临时查询。如果那是您所需要的,请考虑针对用例的更好解决方案,例如如果数据集可能变得任意大,则使用 BigQuery。