在 azure table 存储中创建分区键以存储传感器输出数据的最佳方法是什么?
What is the best way of creating Partition key in azure table storage for storing sensor output data?
我搜索了在 Azure table 存储中存储传感器输出数据的最佳实践,但没有找到最佳答案。我目前正在从事一个项目,该项目包括将传感器数据存储到 azure table 存储中。目前我使用分区键作为 Sensor ID 。我每一秒都在存储传感器输出。目前大约有 100 个传感器正在使用。因此,想象一下每天都在存储大数据。因此,当我按日期搜索特定传感器数据时,我的 Web 应用程序性能变慢。有没有更好的方法来提高网络应用程序的性能?如何将传感器 ID 更改为分区键?代码在这里并不重要。我需要一个合乎逻辑的解决方案..可能这个问题会帮助很多正在处理这种情况的开发人员..
更新
每个传感器提供 10 个不同的输出和日期,即输出日期时间。所以它们在每个传感器 ID 的同一行中。我正在使用 Date range 和 Sensor id
获取传感器数据
分区键 - 传感器 ID,行键 - 日期时间,10 个输出列和输出日期
这是我的代码
var query = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, sensorID);
var dateFilter = TableQuery.CombineFilters(
TableQuery.GenerateFilterConditionForDate("outputdate", QueryComparisons.GreaterThanOrEqual, Convert.ToDateTime(from)),
TableOperators.And,
TableQuery.GenerateFilterConditionForDate("outputdate", QueryComparisons.LessThanOrEqual, Convert.ToDateTime(to))
);
query = TableQuery.CombineFilters(query, TableOperators.And, dateFilter);
var rangeQuery = new TableQuery<TotalizerTableEntity>().Where(query);
var entitys = table.ExecuteQuery(rangeQuery).OrderBy(j => j.date).ToList();
outputdate 表示输出生成时间。这是日期时间。所有输出具有相同的输出时间。
首先,我强烈建议您阅读 Azure Storage Table Design Guide: Designing Scalable and Performant Tables
。这会给你很多关于如何构建数据的想法。
现在开始您当前的实施。我注意到您在查询中包含了 PartitionKey
(顺便说一句,这是非常好的),但随后也在您的查询中添加了一个非索引属性 (outputdate
)。这将导致已知的是 Partition Scan
。对于较大的 tables,这会产生问题,因为您的查询将扫描整个分区以匹配 outputdate
属性。
您提到要存储的 datetime
值为 RowKey
。假设 RowKey
值与 output
日期的值相匹配,我建议在您的查询中使用 RowKey
而不是这个非索引属性。 RowKey
(连同 PartitionKey
)是在 table 中索引的仅有的两个属性,因此查询会相对快得多。
将 date/time 保存为 RowKey
时,我建议将其转换为刻度 (DateTime.Ticks) 然后保存,而不是简单地将 date/time 值转换为字符串.如果您要使用这种方法,我建议在此刻度前添加 0
,以便所有值的长度相同(执行类似 DateTime.Ticks.ToString("d19")
)的操作。
您还可以将 RowKey
保存为 Reverse Ticks
,即 (DateTime.MaxValue.Ticks - DateTime.Ticks).ToString("d20")
。这将确保所有最新条目都添加到 table 的顶部而不是底部。这将有助于您对查询最新记录更感兴趣的场景。
如果您总是查询特定的传感器,将每个传感器的数据保存在单独的 table 中可能不会有什么坏处,即每个传感器都有一个单独的 table。这将为您释放一把钥匙。您可以使用 date/time 值(您当前存储为 RowKey
)作为 PartitionKey
,并且可以使用其他值作为 RowKey
。此外,它还允许您跨存储帐户进行扩展——一些传感器的数据将存储在一个存储帐户中,而其他传感器的数据将存储在其他存储帐户中。您只需要在某个地方保存这种关系,以便数据到达正确的存储 account/table.
我搜索了在 Azure table 存储中存储传感器输出数据的最佳实践,但没有找到最佳答案。我目前正在从事一个项目,该项目包括将传感器数据存储到 azure table 存储中。目前我使用分区键作为 Sensor ID 。我每一秒都在存储传感器输出。目前大约有 100 个传感器正在使用。因此,想象一下每天都在存储大数据。因此,当我按日期搜索特定传感器数据时,我的 Web 应用程序性能变慢。有没有更好的方法来提高网络应用程序的性能?如何将传感器 ID 更改为分区键?代码在这里并不重要。我需要一个合乎逻辑的解决方案..可能这个问题会帮助很多正在处理这种情况的开发人员..
更新
每个传感器提供 10 个不同的输出和日期,即输出日期时间。所以它们在每个传感器 ID 的同一行中。我正在使用 Date range 和 Sensor id
获取传感器数据分区键 - 传感器 ID,行键 - 日期时间,10 个输出列和输出日期
这是我的代码
var query = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, sensorID);
var dateFilter = TableQuery.CombineFilters(
TableQuery.GenerateFilterConditionForDate("outputdate", QueryComparisons.GreaterThanOrEqual, Convert.ToDateTime(from)),
TableOperators.And,
TableQuery.GenerateFilterConditionForDate("outputdate", QueryComparisons.LessThanOrEqual, Convert.ToDateTime(to))
);
query = TableQuery.CombineFilters(query, TableOperators.And, dateFilter);
var rangeQuery = new TableQuery<TotalizerTableEntity>().Where(query);
var entitys = table.ExecuteQuery(rangeQuery).OrderBy(j => j.date).ToList();
outputdate 表示输出生成时间。这是日期时间。所有输出具有相同的输出时间。
首先,我强烈建议您阅读 Azure Storage Table Design Guide: Designing Scalable and Performant Tables
。这会给你很多关于如何构建数据的想法。
现在开始您当前的实施。我注意到您在查询中包含了 PartitionKey
(顺便说一句,这是非常好的),但随后也在您的查询中添加了一个非索引属性 (outputdate
)。这将导致已知的是 Partition Scan
。对于较大的 tables,这会产生问题,因为您的查询将扫描整个分区以匹配 outputdate
属性。
您提到要存储的 datetime
值为 RowKey
。假设 RowKey
值与 output
日期的值相匹配,我建议在您的查询中使用 RowKey
而不是这个非索引属性。 RowKey
(连同 PartitionKey
)是在 table 中索引的仅有的两个属性,因此查询会相对快得多。
将 date/time 保存为 RowKey
时,我建议将其转换为刻度 (DateTime.Ticks) 然后保存,而不是简单地将 date/time 值转换为字符串.如果您要使用这种方法,我建议在此刻度前添加 0
,以便所有值的长度相同(执行类似 DateTime.Ticks.ToString("d19")
)的操作。
您还可以将 RowKey
保存为 Reverse Ticks
,即 (DateTime.MaxValue.Ticks - DateTime.Ticks).ToString("d20")
。这将确保所有最新条目都添加到 table 的顶部而不是底部。这将有助于您对查询最新记录更感兴趣的场景。
如果您总是查询特定的传感器,将每个传感器的数据保存在单独的 table 中可能不会有什么坏处,即每个传感器都有一个单独的 table。这将为您释放一把钥匙。您可以使用 date/time 值(您当前存储为 RowKey
)作为 PartitionKey
,并且可以使用其他值作为 RowKey
。此外,它还允许您跨存储帐户进行扩展——一些传感器的数据将存储在一个存储帐户中,而其他传感器的数据将存储在其他存储帐户中。您只需要在某个地方保存这种关系,以便数据到达正确的存储 account/table.