提问人:jonrexh 提问时间:11/16/2023 更新时间:11/16/2023 访问量:60
存储高频活动数据的最佳数据库选择:SQL 与 NoSQL [已关闭]
Optimal Database Selection for Storing High-Frequency Activity Data: SQL vs NoSQL [closed]
问:
我们正在开发一个应用程序,用于跟踪各种用户活动(如步行、跑步等),包括他们的路线(位置点)、速度和心率(连接到心带时)。每 2-3 秒接收一次数据,为了减少位置数据,我们使用 Douglas-Peucker 算法。
我们的主要挑战是决定最适合我们需求的数据库类型,同时考虑长期性能和可扩展性。我们对 SQL 和 NoSQL 选项都持开放态度。
当前实施: 我们探索了使用
Azure CosmosDB(NoSQL 数据库)Azure CosmosDB (a NoSQL database)
并设计了一个数据模型,其中活动的所有数据存储在“活动”容器内的单个文档中,使用 activityId 作为分区键。文档结构如下所示:
{
"activityId": "123",
"loc_points": [
{"lat": 12, "lng": 13, "alt": 100, "time": "2023-11-16"}
],
"speeds": [
{"speed": 10, "time": "2023-11-16"}
],
"heartRates" : [
{ "heartRate" : 120, "time" : "2023-11-16"}
]
}
替代方法: 我正在考虑的另一个模型是使用三个单独的容器:activityPoints、activityHeartRates 和 activitySpeeds。每个容器将存储由 activityId 链接的相应数据。例如:
{
"activityId": "123",
"loc_points": [...]
}
问题:
鉴于我们应用程序中数据收集的高频性, 在 CosmosDB 中,哪种数据模型更高效、更可缩放:每个活动使用单个文档,还是针对不同数据类型的单独容器?
CosmosDB 中是否有用于有效处理此类时序数据的最佳做法或模式?
在我们的方案中,索引或其他数据库优化是否会显著影响检索时间?
对类似用例的任何见解或经验将不胜感激。
C# Web API 用于后端和 Azure Cosmos SDK 与 Cosmos 交互。
答:
我更关心存储大小,而不是特定的数据库或布局。数据库通常以固定大小的格式存储数据,以简化搜索。您的数据有 9 个字段,为简单起见,假设每个字段 8 个字节,这意味着每行 72 个字节,还有一些额外的索引等开销。这意味着每个用户每小时 ~86Kb,因此,如果您想查看一天的所有活动,数据库需要读取并返回 2Mb。
根据我的经验,大多数时候,像这样的数据通常变化很小,样本很有可能非常接近最后一个样本。根据我的经验,100 的压缩比可能是可行的。但这需要你以块的形式存储数据,比如每个块一个小时。
我的典型压缩方法是首先计算尽可能降低精度,然后计算样本之间的增量,然后通过 gzip 或任何容易获得的压缩算法运行结果。更高级的压缩算法可能会更好,但这种方法相当容易,而且似乎效果很好。这可以将每小时的数据量减少到每小时 864 + 144 字节或每天 ~24kb。这种差异很可能大于数据库类型之间的差异。
此解决方案存在一些明显的潜在缺点。
- 您的数据可能无法很好地压缩
- 您需要在服务器上缓冲数据,例如每个块一个小时。崩溃可能会导致数据丢失。
- 您可能需要在每个字段的块中存储最小值和最大值,以便进行搜索。
- 如果需要在数据库和客户端中同时进行过滤,则会增加复杂性。
- 如果你只想要一个样本,你仍然需要获取和解码整个块。
- 数据库处理可变大小的数据往往比固定大小的数据更差。
我仍然相信这种方法可能是有用的。或者至少承诺花一两个小时来检查您的特定数据的压缩程度。
评论