代码之家  ›  专栏  ›  技术社区  ›  Dave New

具有多个查询点的Azure存储表设计

  •  1
  • Dave New  · 技术社区  · 11 年前

    我有以下Azure存储表。

    位置数据表:

    PartitionKey: ClientID + VehicleID 
    RowKey: GUID 
    Properties:  ClientID, VehicleID, DriverID, Date, GPSPosition
    

    每辆车每年将为每个客户记录多达1000000个实体。每个客户可能拥有数千辆汽车。所以,我决定按 ClientID + VehicleID 所以要有小的、可管理的分区。查询依据时 客户端ID 车辆ID ,操作执行得很快,因为我们将搜索范围缩小到一个分区。

    问题:

    这里的问题是,有时我只需要查询 客户端ID DriverID 。因为无法执行部分PartitionKey比较,所以需要扫描每个分区。这将扼杀性能。

    我不能将PartitionKey全部包含在内 客户端ID , 车辆ID 驱动程序ID 因为查询只会查询 车辆ID 驱动程序ID ,绝不能两者兼而有之。

    解决方案1:

    我考虑在其他地方存储一个值,表示VehicleID和DriverID对,然后 ClientID + VehicleDriverPairID PartitionKey,但这将导致数十万个分区,并且在我的代码中会有很多分区之间的数据统一。

    解决方案2:

    有一个隔板 Client + VehicleID 和另一个分区 Client + DriverID 这意味着更新表需要两倍的工作量(两次更新),但两次查询都会很快。此外,还会有冗余数据。

    这些解决方案听起来可行吗?其他解决方案?

    3 回复  |  直到 11 年前
        1
  •  4
  •   Yves Goeleven    11 年前

    您应该像解决方案2中那样复制这些记录。我建议保留一个副本,每个记录都在自己的分区中,因此也由vehicleid进行分区,这将使更新所有副本变得更容易,从vehicleid开始并传播到其他副本。

    存储数据真的很便宜,除非事先正确存储,否则查询就是一个皮塔。所以我的建议是:重复!

        2
  •  1
  •   David S.    11 年前

    因为不可能执行部分PartitionKey比较, 每个分区都需要进行扫描。

    不是真的。例如,如果您的分区键是(字面上) ClientID$VehicleID ,您可以扫描 PartitionKey gt 'ClientID$' and PartitionKey lt 'ClientID%' (之所以有效,是因为 (Char)($+1) % 。这将只扫描以ClientID开头的分区。

        3
  •  1
  •   Dave New    11 年前

    在这里,RowKey似乎是一个没有意义的GUID,只是为了唯一性,可以替换/增强它,并提出以下内容。

    每个插入都是对同一分区的2个实体的插入,因此可以进行批处理,以便两者都成功或失败,从而确保一致性。[]中的注释值是可选的。

    PartitionKey = ClientID  
    RowKey = [Prefix] + VehicleID + [Suffix]
    

    PartitionKey = ClientID  
    RowKey = [Prefix] + DriverID + [Suffix]
    

    如果 VehicleID DriverID 它们之间并不是唯一的,可以通过添加前缀(如“V”和“D”)使它们唯一。

    如果需要RowKey的唯一性,则可以用日期作为后缀(如果足够的话),或者用当前完成的GUID作为后缀。