【问题标题】:Is there a way to get distinct PartionKeys from a Table有没有办法从表中获取不同的 PartionKey
【发布时间】:2012-10-12 15:37:20
【问题描述】:

目前,我使用 PartitionKey 来区分将数据存储到 Azure 表服务中的设备。我想构建一个允许我浏览该数据的查看器,但是能够对其进行结构化以便我可以“按设备”或按 PartitionKey 查看数据会很好。查看器应用程序不知道存在哪些设备,因此如果我能以某种方式获取给定表中不同 PartionKeys 的列表,那就太好了。这是可能的,还是我将被降级为创建一个元数据表,在其中为每个设备插入一个新行,然后使用它进行查询?

【问题讨论】:

    标签: .net azure azure-table-storage


    【解决方案1】:

    创建一个表来存储您的分区。按您使用的表名对表进行分区,并为您创建的每个分区添加一个条目。

    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, });
    

    我打赌这可以优化。

    【讨论】:

      【解决方案2】:

      我认为没有办法检索所有分区键。不过,这是一个巧妙的解决方法:https://docs.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 文档的链接。

      【讨论】:

      • 这种方法不会导致全表扫描吗?更好的方法是为每个分区(设备)创建一个单独的表,或者创建一个仅包含有关每个设备的信息的表(一种主细节方法)。
      • @GauravMantri - 是的,我认为这可能会导致整个表扫描。我想这是一个问题,您是否希望减少创建和管理附加表的开销,或者提高执行扫描的效率——这将取决于您的用例和数据量。不过,您不需要单独的表 - 除了其他分区的键之外什么都没有的索引分区也可以。
      • 没有办法返回所有分区(今天)。您必须扫描整个表才能知道。使用计算分区键的元数据或通用算法。
      • @jschmitter 谢谢。固定。
      【解决方案3】:

      遗憾的是,Azure 表没有 distinct 或其他功能 - 将其视为基于结构化键的存储,例如内存中的字典。您执行的任何操作都必须遍历所有项目才能获得其中的一个子集,除非您知道要首先加载哪些键并处理该子列表。

      我个人会简单地使用第二个 azure 表并将分区键存储在那里(作为行键),然后您就有机会按另一个因素对它们进行分组。或者只是对第二个表使用单个分区键。

      这会给你最好的性能和最少的头痛。

      有时,最简单的方法是最好的方法,因为您可以完成工作。

      希望这会有所帮助,

      【讨论】:

        【解决方案4】:

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

        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();
        ...
        

        upper 和你的在大型(运行 7000 万行表 - 大约 2 小时)或中型但有许多属性表上工作非常缓慢

        【讨论】:

          【解决方案5】:

          这将为您提供表中所有分区键的列表:

          ConcurrentDictionary<string, byte> partitionKeys = new ConcurrentDictionary<string, byte>();
          Parallel.ForEach(myTable.ExecuteQuery(new TableQuery()), entity =>
          {
              partitionKeys.TryAdd(entity.PartitionKey, 0);
          });
          

          即使您有一个大表,它也应该快速填充,因为它是并行运行的。如果你愿意的话,没有“ConcurrentSet”,所以我们必须使用 ConcurrentDictionary。字节只是一个占位符;所有值都将在 partitionKeys.Keys 中。

          【讨论】:

          • 查询不会并行运行,这将枚举整个表。
          • 此查询将枚举整个表。您正在本地过滤结果。
          猜你喜欢
          • 2019-07-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-30
          • 1970-01-01
          • 1970-01-01
          • 2018-09-25
          • 2014-01-02
          相关资源
          最近更新 更多