Azure 存储 table 记录过滤建议
Azure storage table records filtering advice
使用 Azure 存储构建类似博客发布系统的图像 Table。
用户发布一条消息,数据库会同时记录用户的地区、城市和语言。
之后,用户可以浏览所有其他用户的帖子,并可以按地区、城市和语言的任意组合进行过滤。或者两者都不是,然后全部查看。
我看到了几种解决方案:
- 将每条消息放入 8 个不同的分区中,并结合区域-城市-语言(优点:读取时闪电般快速的点查询;缺点:写入时每条消息 8 个事务)。
- 将每条消息放在 4 个不同的分区中,结合 Region-City 和进行分区扫描以按语言过滤的能力(优点:事务少于 (1);缺点:分区扫描,每条消息 4 个事务)。
- 根据用户 ID 将每条消息放入分区(优点:每条消息单个事务;缺点:慢 table 扫描和分区扫描)。
我的看法:
- 读取速度快,写入速度慢(可能成本高)。
- 平衡reads/writes/cost.
- 写入速度快,读取速度慢(但便宜)。
"cost/cheap" 我的意思是基于交易的定价(而不是 space)。
"balanced" 我的意思是仅在这些变体中。
考虑过使用索引 tables,但看不到他们在这里有什么帮助。
所以问题是,也许还有另一种更好的方法?
这取决于您的场景和 read/write 模式。您可能需要考虑一些方面:
设计查询记录的方式。将它们放入带有消息 ID 作为实体数据的 "Region-City-Language" 分区中可能有助于您的快速查询。
每条消息可能有一个唯一的消息ID,ID-Message映射保存在其他table中,那么每次只需要更新一个table消息被更新,其他table引用的消息ID保持不变。
在您的 table 设计和查询实体中利用这两个键的 ParitionKey 和 RowKey。例如:"Region-City-Language" 作为分区键,"User" 作为行键。
考虑为查询场景存储实体的重复副本。例如,如果您有大量基于用户和基于语言的查询,您可以考虑使用两个 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。
使用 Azure 存储构建类似博客发布系统的图像 Table。 用户发布一条消息,数据库会同时记录用户的地区、城市和语言。
之后,用户可以浏览所有其他用户的帖子,并可以按地区、城市和语言的任意组合进行过滤。或者两者都不是,然后全部查看。
我看到了几种解决方案:
- 将每条消息放入 8 个不同的分区中,并结合区域-城市-语言(优点:读取时闪电般快速的点查询;缺点:写入时每条消息 8 个事务)。
- 将每条消息放在 4 个不同的分区中,结合 Region-City 和进行分区扫描以按语言过滤的能力(优点:事务少于 (1);缺点:分区扫描,每条消息 4 个事务)。
- 根据用户 ID 将每条消息放入分区(优点:每条消息单个事务;缺点:慢 table 扫描和分区扫描)。
我的看法:
- 读取速度快,写入速度慢(可能成本高)。
- 平衡reads/writes/cost.
- 写入速度快,读取速度慢(但便宜)。
"cost/cheap" 我的意思是基于交易的定价(而不是 space)。 "balanced" 我的意思是仅在这些变体中。
考虑过使用索引 tables,但看不到他们在这里有什么帮助。 所以问题是,也许还有另一种更好的方法?
这取决于您的场景和 read/write 模式。您可能需要考虑一些方面:
设计查询记录的方式。将它们放入带有消息 ID 作为实体数据的 "Region-City-Language" 分区中可能有助于您的快速查询。
每条消息可能有一个唯一的消息ID,ID-Message映射保存在其他table中,那么每次只需要更新一个table消息被更新,其他table引用的消息ID保持不变。
在您的 table 设计和查询实体中利用这两个键的 ParitionKey 和 RowKey。例如:"Region-City-Language" 作为分区键,"User" 作为行键。
考虑为查询场景存储实体的重复副本。例如,如果您有大量基于用户和基于语言的查询,您可以考虑使用两个 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。