Azure 存储 table 记录过滤建议

Azure storage table records filtering advice

使用 Azure 存储构建类似博客发布系统的图像 Table。 用户发布一条消息,数据库会同时记录用户的地区、城市和语言。

之后,用户可以浏览所有其他用户的帖子,并可以按地区、城市和语言的任意组合进行过滤。或者两者都不是,然后全部查看。

我看到了几种解决方案:

  1. 将每条消息放入 8 个不同的分区中,并结合区域-城市-语言(优点:读取时闪电般快速的点查询;缺点:写入时每条消息 8 个事务)。
  2. 将每条消息放在 4 个不同的分区中,结合 Region-City 和进行分区扫描以按语言过滤的能力(优点:事务少于 (1);缺点:分区扫描,每条消息 4 个事务)。
  3. 根据用户 ID 将每条消息放入分区(优点:每条消息单个事务;缺点:慢 table 扫描和分区扫描)。

我的看法:

  1. 读取速度快,写入速度慢(可能成本高)。
  2. 平衡reads/writes/cost.
  3. 写入速度快,读取速度慢(但便宜)。

"cost/cheap" 我的意思是基于交易的定价(而不是 space)。 "balanced" 我的意思是仅在这些变体中。

考虑过使用索引 tables,但看不到他们在这里有什么帮助。 所以问题是,也许还有另一种更好的方法?

这取决于您的场景和 read/write 模式。您可能需要考虑一些方面:

  1. 设计查询记录的方式。将它们放入带有消息 ID 作为实体数据的 "Region-City-Language" 分区中可能有助于您的快速查询。

  2. 每条消息可能有一个唯一的消息ID,ID-Message映射保存在其他table中,那么每次只需要更新一个table消息被更新,其他table引用的消息ID保持不变。

  3. 在您的 table 设计和查询实体中利用这两个键的 ParitionKey 和 RowKey。例如:"Region-City-Language" 作为分区键,"User" 作为行键。

  4. 考虑为查询场景存储实体的重复副本。例如,如果您有大量基于用户和基于语言的查询,您可以考虑使用两个 table 分别将 "user" 和 "language" 作为键。

另请参阅 https://azure.microsoft.com/en-us/documentation/articles/storage-table-design-guide/ 以获取完整指南。

我决定使用 (1) 的变体。

区别在于我不会存储区域-位置-语言的所有组合。相反,我决定只存储唯一性:

Table: FiltersByRegion
----------------------
Partition:  Region
Row:        Location.Language
Prop:       Message

Table: FiltersByRegionPlace
---------------------------
Partition:  Region.Location
Row:        Language
Prop:       Message

Table: FiltersByRegionLanguage
------------------------------
Partition:  Region.Language
Row:        Location
Prop:       Message

Table: FiltersByLanguage
------------------------
Partition:  Language
Row:        Region.Location
Prop:       Message

由于我只存储唯一性,因此每个 post 不会有很多交易。只有那些不存在于数据库中的。

换句话说,如果有很多 posts 来自相同的地区-位置-语言,过滤器 tables 将不会更新,交易也不会花费。唯一性测试可以使用 Redis 来加快速度。

过滤现在只是选择正确的问题 table。