我搜索了将传感器输出数据存储在azure表存储中的最佳实践,但没有得到最佳答案。我目前正在开展一个项目,包括将传感器数据存储到azure表存储中。目前我使用分区密钥作为传感器ID。我每秒都存储传感器输出。目前约有100个传感器正在使用。因此,想象大数据每天都在存储。因此,当我按日期搜索特定传感器数据时,我的Web应用程序性能会变慢。有没有更好的方法来改善Web应用程序的性能?如何将传感器ID更改为日期作为分区键?代码在这里并不重要。我需要一个合乎逻辑的解决方案..可能这个问题会帮助很多正在开发此类场景的开发人员。
更新
每个传感器提供10个不同的输出和日期,即输出日期时间。因此它们位于每个传感器ID的同一行中。我正在使用日期范围和传感器ID
获取传感器数据分区键 - 传感器ID,RowKey - 日期时间,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表示输出生成时间。这是日期时间。所有输出都具有相同的输出时间。
答案 0 :(得分:2)
首先,我强烈建议您阅读Azure Storage Table Design Guide: Designing Scalable and Performant Tables
。这将为您提供有关如何构建数据的大量想法。
现在进入你当前的实施。我注意到的是,您在查询中包含PartitionKey
(这是非常好的BTW),但在您的查询中也添加了非索引属性(outputdate
)。这将导致所谓的Partition Scan
。对于较大的表,这会产生问题,因为您的查询将扫描整个分区以匹配outputdate
属性。
您提到存储的datetime
值为RowKey
。假设RowKey
值与output
日期的值匹配,我建议您在查询中使用RowKey
而不是此非索引属性。 RowKey
(以及PartitionKey
)是表中索引的唯一两个属性,因此查询速度会相对快得多。
将日期/时间保存为RowKey
时,我建议将其转换为刻度(DateTime.Ticks),然后保存,而不是简单地将日期/时间值转换为字符串。如果您采用这种方法,我建议在此刻度之前加上0
,以便所有值都具有相同的长度(执行DateTime.Ticks.ToString("d19")
之类的操作。)
您还可以将RowKey
保存为Reverse Ticks
,即(DateTime.MaxValue.Ticks - DateTime.Ticks).ToString("d20")
。这将确保将所有最新条目添加到表格的顶部而不是底部。这将有助于您更有兴趣查询最新记录。
如果您将始终查询特定传感器,则在单独的表中保存每个传感器的数据可能没什么坏处,即每个传感器都有一个单独的表。这将为您释放一把钥匙。您可以将日期/时间值(当前存储为RowKey
)用作PartitionKey
,并可以使用其他值作为RowKey
。此外,它还允许您跨存储帐户进行扩展 - 某些传感器的数据将放在一个存储帐户中,而其他传感器的数据将放入其他存储帐户。在某处您只需要保存此关系,以便数据到达正确的存储帐户/表。