有没有一种方法可以从表中获取不同的PartitionKey?

16

目前,我正在使用PartitionKey来区分将数据存储到Azure Table服务中的设备。 我想构建一个查看器,允许我浏览这些数据,但是如果能够按“设备”或PartitionKey结构化数据以便查看将会很好。 查看器应用程序不知道存在哪些设备,因此如果我能以某种方式返回给定表中不同PartitionKeys的列表,那将非常好。这是可能的吗?还是我只能创建一个元数据表,在其中为每个设备插入一行,然后用于查询?

5个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
16
创建一个表来存储你的分区。按照你使用的表名对表进行分区,并为每个分区添加一个条目。
public class PartitionEntry : TableServiceEntity { }

tableServiceContext.AddObject("TablePartitions", new PartitionEntry
{
    PartitionKey = "<table name>",
    RowKey = "<partition key>",
});
tableServiceContext.BeginSaveChanges(SaveChangesOptions.ContinueOnError, null, null);

然后只需查询此表以获取分区列表。对我来说非常易于管理。

var tbl = tableServiceContext.CreateQuery<PartitionEntry>("TablePartitions");
return tbl.Where(i => i.PartitionKey == "<table name>")
          .Select(i => new { PartitionKey = i.RowKey, });

我敢打赌这可以被优化。


9
我认为没有一种方法可以检索所有的分区键。 这里有一个聪明的解决方法: https://learn.microsoft.com/en-gb/archive/blogs/avkashchauhan/retrieving-partition-key-range-in-windows-azure-table-storage。引用Avkash博客的话: 深入挖掘后,我发现没有内置的API来获取分区键列表,因此我必须为自己创建一个解决方案。所以我最终在每个分区中插入一个虚拟行,当我想要获取分区键列表时,我只需查询这些虚拟项,它们会给我所需的列表。 我相信您已经看过了这篇文章,但对于可能遇到此问题的其他人,我认为这是关于表服务功能的最佳指南: http://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-tables/,其中包含示例和链接到详细的API文档。

8
这种方法是否会导致对整张表进行全表扫描?更好的方法是要么为每个分区(设备)创建一个单独的表,要么创建一张仅包含有关每个设备信息的表(类似于主从表的方法)。 - Gaurav Mantri
4
@GauravMantri - 是的,我认为这可能会导致整个表扫描。我想这是一个问题,是否您希望在创建和管理其他表时减少开销,还是在执行扫描时提高效率 - 这将取决于您的使用情况和数据量。但是您并不需要一个单独的表 - 仅包含指向其他分区的键的索引分区也可以。 - Jude Fisher
2
今天还没有办法返回所有分区。您必须扫描整个表才能知道。使用元数据或通用算法来计算分区键。 - dunnry
@jschmitter 谢谢。已修复。 - Jude Fisher

6
很遗憾,Azure Tables 没有像 distinct 或其他函数一样的功能。将其视为类似于内存中的字典的结构化基于键的存储。您执行的任何操作都必须迭代所有项目,以便获取其中的子集,除非知道要先加载哪些键并处理该子列表。 我个人会简单地使用第二个 Azure 表,并将分区键存储在其中(作为行键),这样可以让您有机会按另一个因素对它们进行分组。或者只是为此第二个表使用单个分区键。 这将为您提供最佳性能和最少的麻烦。 有时,最简单的方法是最好的方法,因为您可以完成工作。 希望这可以帮助到您。

0

我之前尝试过类似的方法:

TableQuery queryRows = new TableQuery() { SelectColumns = new List<string> { "PartitionKey" } };
... 
var tableClientSrc = storageAcctScr.CreateCloudTableClient();
var tablesSrc = tableClientSrc.ListTables();
var tableSrc = tablesSrc.FirstOrDefault(o => o.Name.Equals(nameSrc));
int cntSrc = tableSrc.ExecuteQuery(queryRows).Count();
...

在大型表(约7000万行)或中等但具有许多属性的表上,您和您的工作速度非常慢。


-2

以下代码将返回表中所有分区键的列表:

ConcurrentDictionary<string, byte> partitionKeys = new ConcurrentDictionary<string, byte>();
Parallel.ForEach(myTable.ExecuteQuery(new TableQuery()), entity =>
{
    partitionKeys.TryAdd(entity.PartitionKey, 0);
});
即使您有一个大表,它也应该快速填充,因为它是并行运行的。如果您愿意,没有“ConcurrentSet”,因此我们必须使用ConcurrentDictionary。字节只是一个占位符;所有值都将在partitionKeys.Keys中。

这些查询不会并行运行,这将枚举整个表。 - tster
此查询将枚举整个表。您正在本地过滤结果。 - kevinj
这对于一个大表格来说不太好 :))) - tymtam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,