在Azure表存储中基于标签查询大量行最有效的方法是什么?
我需要找到所有已标记至少"A"one_answers"B"标签的行。标签将在插入之前被规范化,例如。只能使用小写字母和数字。我还需要轻松地取出最新的项目,因此我当前的RowKey
包含一个反向的DateTime
作为string.Format("{0:D19}", DateTime.MaxValue.Ticks-DateTime.UtcNow.Ticks)
我所有的行都是由一个UserId
我目前的解决方案是为每个标记添加额外的行(考虑将它们放在单独的表中),然后我可以启动多个查询并在将它们返回给客户端之前在服务器上连接它们。因此,当插入一个有两个标签(a, B)的实体时,它将像这样存储:
[
{
"partitionKey": "123", // UserId
"rowKey": "2519633682044852820"
},
{
"partitionKey": "123_tags", // UserId + tags constant, this is not the actual tags - this is to put the tagged entities in a different partition
"rowKey": "a" // normalized tag
},
{
"partitionKey": "123_tags",
"rowKey": "b"
}
]
我需要的查询,将是这样的:
-
top 1000 latest entities where userId = "X"
-
all entities where userId = "X" and tags contains "A" AND "B"
这取决于单个用户的数据量。第一个查询很简单,因为分区键是用户id。当涉及到第二个查询时,由于表存储中没有"包含"功能,我会说您有以下选项:
- 获取用户的所有项,并在代码中过滤掉不必要的记录(如果每个用户没有那么多记录,应该不会有问题)
- 如果单个用户的记录太多,您可以根据一些标签范围为用户分区记录,即分区键可以看起来像"UserX_TagsA-K","UserX_TagsK-O","UserX_TagsO-Z",然后只从需要的范围中获取,然后在代码中过滤掉
- 为每个标记创建冗余记录,那么分区键对于一条记录可以是"UserX_Tag123",对于同一条记录可以是"UserX_Tag324",但是表明它有两个标记。如果数据需要更新,行键可以是一个复合的,即以以下格式"GroupId:UniqueId",并通过在行键上使用"StartsWith"子句,您可以获得所有冗余的记录来更新它们
无论哪种方式,表存储架构都不会使这样的用例变得容易,您需要在代码中实现一些逻辑。
另外,IIRC可以使用默认的TimeStamp字段获取最新的项目。
您目前的设计看起来不错,它符合Azure存储表设计指南中的指导方针。您提到的2个查询可以在您设计的表中有效地完成。你还有其他问题吗?