存储高频活动数据的最佳数据库选择:SQL 与 NoSQL [已关闭]

Optimal Database Selection for Storing High-Frequency Activity Data: SQL vs NoSQL [closed]

提问人:jonrexh 提问时间:11/16/2023 更新时间:11/16/2023 访问量:60

问:


想改进这个问题吗?更新问题,以便可以通过编辑这篇文章用事实和引文来回答。

6天前关闭。

我们正在开发一个应用程序,用于跟踪各种用户活动(如步行、跑步等),包括他们的路线(位置点)、速度和心率(连接到心带时)。每 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 交互。

C# SQL 数据库 NoSQL Azure-CosmosDB

评论

0赞 Stefano Cucchi 11/16/2023
嗨,我建议您考虑读取应用程序的速度和易用性,当您没有每秒 1000 个数据之类的东西时,写入在 SQL 上也不是问题
0赞 JonasH 11/16/2023
可靠性要求是什么?此类数据通常可以高度修改为压缩,但压缩要求您将数据存储在块中,例如每小时一个块。但是,如果在内存中缓冲,则如果服务器由于某种原因崩溃,它将丢失。筛选也可能稍微复杂一些,因为您无法在数据库中执行所有筛选。
0赞 David Makogon 11/16/2023
只是没有办法客观地回答这个问题。另外:“sql vs nosql”并不是一回事:NoSQL是非关系数据库(可以是键/值、文档、列、图形,甚至是组合/混合)的通用术语。此外,SQL数据库还有几个“品牌”。您的选择将取决于您和您的数据,以及查询模式、第三方工具、报告需求、读写需求等。这实际上与 Cosmos DB(或 C#)无关
0赞 jonrexh 11/16/2023
@DavidMakogon 感谢您的见解。我们目前更关注读取性能,而不是写入性能。虽然我提到从 Cosmos DB 开始,但我对 SQL 和 NoSQL 数据库的建议持开放态度。如果您对擅长处理类似类型数据的数据库有任何建议或经验,尤其是具有高效读取功能的数据库,我将不胜感激您的意见。无论是特定类型的 SQL 数据库还是 NoSQL 数据库,我都有兴趣探索所有可行的选项,以确保我们做出最适合应用程序需求的明智决策
0赞 David Makogon 11/16/2023
推荐问题以及讨论/意见问题在这里显然是题外话。你基本上是在要求围绕不同的方法进行对话,以及数据库建议。这确实应该发布到一般讨论论坛(例如reddit)。

答:

0赞 JonasH 11/16/2023 #1

我更关心存储大小,而不是特定的数据库或布局。数据库通常以固定大小的格式存储数据,以简化搜索。您的数据有 9 个字段,为简单起见,假设每个字段 8 个字节,这意味着每行 72 个字节,还有一些额外的索引等开销。这意味着每个用户每小时 ~86Kb,因此,如果您想查看一天的所有活动,数据库需要读取并返回 2Mb。

根据我的经验,大多数时候,像这样的数据通常变化很小,样本很有可能非常接近最后一个样本。根据我的经验,100 的压缩比可能是可行的。但这需要你以块的形式存储数据,比如每个块一个小时。

我的典型压缩方法是首先计算尽可能降低精度,然后计算样本之间的增量,然后通过 gzip 或任何容易获得的压缩算法运行结果。更高级的压缩算法可能会更好,但这种方法相当容易,而且似乎效果很好。这可以将每小时的数据量减少到每小时 864 + 144 字节或每天 ~24kb。这种差异很可能大于数据库类型之间的差异。

此解决方案存在一些明显的潜在缺点。

  • 您的数据可能无法很好地压缩
  • 您需要在服务器上缓冲数据,例如每个块一个小时。崩溃可能会导致数据丢失。
  • 您可能需要在每个字段的块中存储最小值和最大值,以便进行搜索。
  • 如果需要在数据库和客户端中同时进行过滤,则会增加复杂性。
  • 如果你只想要一个样本,你仍然需要获取和解码整个块。
  • 数据库处理可变大小的数据往往比固定大小的数据更差。

我仍然相信这种方法可能是有用的。或者至少承诺花一两个小时来检查您的特定数据的压缩程度。