【问题标题】:Large Sensor Data best option. Tables SQL Vs Azure Table [closed]大型传感器数据最佳选择。表 SQL 与 Azure 表 [关闭]
【发布时间】:2021-12-26 21:56:32
【问题描述】:

我想要一些关于最佳选择的建议,因为我在基于 Web 的 API 上检索数据的速度很慢(超过 30 秒)。

我有多个 IoT 传感器(超过 100 个),并且随着 TX 将传感器数据更新到我的 IoT 中心,这些传感器数据也会不断增长,然后将其保存到数据库或存储中。

以前我将所有传感器数据保存到 SQL 表中,但随着数据的增长,我发现它变得非常慢,因此我使用了 Azure 表存储。每个 Sensor 都有自己独立的表存储,分区键是月份和年份(例如 202012),行键是时间戳(例如 0002518033824243332546)。

事实证明这要快得多,因为传感器数据量减少了,因为每个传感器都有自己的表,但是随着表的增长对于任何特定的传感器,我需要在更长的时间内检索数据(1月)这再次变得非常缓慢。每个传感器 TX 每 1 分钟更新一次,因此每天产生 1400 条记录,1 个月大约有 44640 条记录。

有没有更好的解决方案来满足我的要求?

为每个传感器创建一个单独的 SQL 表是个好主意吗? SQL 存储中可以有多少张表?

谢谢

【问题讨论】:

  • 您真的需要历史报告的所有数据吗?如果不是,如何存储汇总数据以进行更长时间的报告?
  • 如果不知道您如何使用所有传感器数据,就不可能回答您的问题。一个传感器一个传感器?一个小时一个小时?搜索异常值?历史图表?要不然是啥?请edit您的问题或询问其他问题。通常,这是一种糟糕的数据库设计,需要在应用程序扩展时创建更多的表。正确索引的大表比许多表工作得更好。
  • 是的,样本需要用于平均目的,但首先我需要先检索数据。一旦我们得到原始数据,我们就会在一小时内对其进行平均。这是每个传感器完成的

标签: sql azure azure-sql-database azure-table-storage


【解决方案1】:

您可以考虑使用 Azure SQL 数据库(高级 P6 或更高级别)来存储来自冷路径(存储帐户)或来自需要直接保存到数据库的热路径的 IoT 数据。

首先考虑使用提到的列存储索引来优化数据存储here。有了它,您可以将数据压缩多达 20 倍,并快速将更多数据检索到内存中。

CREATE TABLE Telemetry (
    _id bigint IDENTITY,
    sensorData nvarchar(max),
   INDEX cci CLUSTERED COLUMNSTORE
)

其次,您可以考虑在 Transact-SQL 中使用 In-Memory OLTPJSON functions。这样,您可以将格式为 JSON 的数据视为任何其他 SQL 数据类型,并从 JSON 文本中提取值以在 SELECT 列表或搜索谓词中使用 JSON 数据。由于基于列存储的表针对扫描和聚合而不是键查找查询进行了优化,因此您还可以基于 JSON 函数创建计算列,然后将原始 JSON 列中的特定属性作为常规关系列公开,从而简化查询设计和开发。您可以通过在计算列上创建常规(基于行的)非聚集索引来进一步优化数据检索,以支持关键查询和访问路径。虽然这些会略微增加整体存储需求,但它们将帮助查询处理器在键查找和范围扫描中过滤行,并且还可以帮助其他操作,如聚合等。请注意,您可以随时添加计算列和相关索引。

如果您的 JSON 结构稳定且预先已知,最好的选择是设计我们的关系架构以容纳 JSON 数据中最相关的属性,并在插入新数据时利用 OPENJSON 函数将这些属性转换为行字段.这些将是完全关系列(具有优化的 SQL 数据类型),可用于各种检索和分析目的,从复杂的过滤到聚合,您只需要创建适当的索引来支持各种访问路径。但是,如果可能需要进一步处理,您仍然可以决定保留整个 JSON 片段并将其存储在同一个表的 VARCHAR(max) 字段中。

如果您可以将 IoT 数据保存为具有 SQL 数据类型的行字段,请考虑使用基于时间的表分区。将所有数据放在一个表中,但按日期范围进行分区,如 here 所述。

【讨论】:

  • 我会阅读更多内容以获得更好的理解,但这是否意味着每个传感器在数据库中将有 1 行,并且在该行中将有 JSON 数据类型,得到更新(带有时间戳)并阅读?目前我的 JSON 是结构化的,但将来如果我引入新的传感器或新数据,我该如何处理?使用 CLUSTERED COLUMNSTORE INDEX,当您想要读取数据时解压缩数据的时间呢?以前我有一个 SQL 表,所有传感器数据都在它自己的列中,例如电池、data1、data2、温度等
  • 如果目前 JSON 数据是结构化的,但将来可能不是,则将来自 IOT 设备的数据存储在 varchar(max) 列上(阅读第三段)。每个来自 IoT 设备的 JSON 读数都将作为单独的行保存在表中。 CREATE TABLE Telemetry (_id bigint IDENTITY, sensorData nvarchar(max), INDEX cci CLUSTERED COLUMNSTORE)
  • 您可以混合使用这两种方法,在表中创建包含相关数据的列,并将数据另存为 JSON。然后,您可以使用非聚集索引和列存储索引进行搜索
  • 每个传感器是否有可能只有 1 行。此行可以具有不会更改的静态数据,并且所有更改的数据类型都具有 JSON 数据类型。 JSON 数据类型是否有最大大小?如何在不删除任何先前条目的情况下更新该列?
  • 这将使数据检索复杂化,因为您将在一个数据行的一个 varchar(MAX) 单元格中从一个传感器获得数百万个读数。您将无法按日期对读数进行分区,您还将无法将格式为 JSON 的数据视为任何其他 SQL 数据类型,并从 JSON 文本中提取值以在 SELECT 列表或搜索谓词中使用 JSON 数据。您也无法利用 Json 函数。这里的重点不是将许多数据放在一个单元格或行属性中,而是以一种使数据检索简单快捷的方式存储数据。
【解决方案2】:

一般来说,就性能而言,在写入期间进行聚合比在读取期间进行聚合更好。为数据的多个视图构建多个表。例如,一个包含过去 24 小时原始数据的表,一个包含上个月每小时的汇总数据,另一个包含去年每天的汇总数据。

根据您的评论:

是的,样本需要用于平均目的,但首先我需要先检索数据。一旦我们得到原始数据,我们就会在一小时内对其进行平均。这是每个传感器完成的

存储数以百万计的原始数据只是为了将它们全部读入内存并通过在内存中聚合来大大减少数据点是没有意义的。这是对存储和处理能力的浪费。

有没有更好的解决方案来满足我的要求?

什么要求?我没有看到。无论如何,根据您提供的信息:我建议不要使用像 sql server 这样的 rdbms,而是寻找一些专门为此类数据构建的存储,例如 Azure Time Series Insight。它integrates nicely 与 IoT 中心

根据评论:

已经提到,最好是聚合。也许那时我可以使用 Azure Tables 并聚合数据。

是的,你可以。这里也有很多选择。要进行聚合,您可以编写一个 azure function triggered by the IoT Hub 来聚合和存储数据。或者您可以利用Azure Stream Analytics 创建不同的聚合并将它们发送到the desired output。另一种选择是使用Cosmos DB 作为数据存储,并使用Change Feed 创建不同的聚合视图。

如您所见,有很多选择。哪一个最适合您的场景取决于预算、性能限制(是否也需要全球可用?)、可扩展性等。

顺便说一句,为将来的问题获得更好的答案的提示:告诉我们用例。你需要这些数据做什么?你想要什么样的查询和/或可视化,你想要执行什么样的分析?

【讨论】:

  • 关于数据的用途,我有各种传感器,每分钟报告空气质量、温度、湿度、光线。然后使用 Azure Function App,我创建了网站可以访问的 API。然后,用户可以查看所有传感器数据的历史记录。
  • 已经提到,最好是聚合。也许那时我可以使用 Azure Tables 并聚合数据。
  • @user8400863 查看更新后的答案。
【解决方案3】:

为每个传感器创建一个单独的 SQL 表是个好主意吗? SQL 存储中可以有多少张表?

可以无限制地创建表,因为它只是磁盘上的一个文件。

但我认为自动化不是个好主意。

因为您每次都必须为新传感器创建新表。

我建议您对所有传感器只使用一张表,并为传感器 id 添加分区键。

创建表或创建分区是相同的概念,因为两者都会在磁盘上创建新的物理文件。

所以从哪个表获取和从哪个分区获取没有速度差异。

但是当您想要获取两个或更多月的数据时,您的问题仍然存在,因为它访问多个分区(多个文件)。

有没有更好的解决方案来满足我的要求?

我认为您需要运行批处理程序,如@Peter Bons 评论的那样为您的报告创建汇总表。

从求和表中获取到昨天,从当前表中获取今天,合并两个数据得到结果会更快。

【讨论】:

  • 只进不直接将存储部分操作进RDBMS引擎的poro品质RDBMS(PostGreSQL, MySQL, Access...),表不是一个文件...
  • 与为每个传感器创建一个文件相比,创建分区似乎是个好主意。我想这样当我手动查看表格时,我不需要滚动 100 个表格文件来找到我需要查看的传感器。正如您提到的,两个月后我会遇到同样的问题,因为我正在读取多个分区,但如果我一次只读取一个传感器,那会是一个问题,因为我只读取 1 个分区吗?所以这个批处理程序会简单地更新另一个表,但使用平均数据?也许每天安排一次平均?
  • @SQLpro 我认为这只是他们的决定,是为所有模式(表、索引、分区...)创建一个文件还是为每个模式创建每个文件。例如,MS 决定在 2007 年后为每个工作表、图表、主题、样式...制作每个 XML 文件,而不是一个二进制文件。
  • @user8400863 如果我一次只读取一个传感器,这会是一个问题,因为我只读取 1 个分区吗? -> 如果分区很大并且不要在过滤器中使用索引列,则可能是一个问题,因为它将读取分区中的所有行。这个批处理程序会简单地更新另一个表,但使用平均数据? -> 是的,创建一些平均表。例如:如果报告显示每个传感器的平均温度,小时,您可以按传感器,小时分组并选择温度平均值而不是 60 个温度。也许每天安排一次平均? -> 如果数据不是太大,一天一次是常见的。
  • 谢谢,我会尝试这些选项
猜你喜欢
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 2019-11-20
  • 2012-01-02
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多