我是 Azure 的新手!目的是根据 RowKey 中存储的时间戳返回行。由于每个查询都有交易成本,我希望在保持性能的同时最大限度地减少交易/查询的数量
这些是建议的分区和行键:
- 分区键: TextCache_(AccountID)_(ParentMessageId)
- 行键: (DateOfMessage)_(MessageId)
图例:
- AccountId - 是一个整数
- ParentMessageId - 父级消息Id(如果有),如果是父级则为空
- DateOfMessage - 创建消息的日期 - 格式为 DateTime.Ticks.ToString("d19")
- MessageId - 消息的唯一 ID
我想从单个查询中返回 > 或 < DateOfMessage_MessageId 的行和任何子行
这可以通过我建议的 PartitionKeys 和 RowKeys 来完成吗?
即..(伪代码)
var results = ctx.PartitionKey.StartsWith(TextCache_AccountId)
&& ctx.RowKey > (TimeStamp)_MessageId
其次,如果我有多个帐户,并且只想返回前 10 个帐户,是否可以通过单个查询来完成
即..(伪代码)
var results = (
(
ctx.PartitionKey.StartsWith(TextCache_(AccountId1)) &&
&& ctx.RowKey > (TimeStamp1)_MessageId1 )
)
||
(
ctx.PartitionKey.StartsWith(TextCache_(AccountId2)) &&
&& ctx.RowKey > (TimeStamp2)_MessageId2 )
) ...
)
.Take(10)
最佳答案
对您的问题的简短回答是肯定的,但您需要注意一些事情。
Azure 表存储没有直接等效于 .StartsWith()
的功能。如果您将存储库与 LINQ 结合使用,则可以使用 .CompareTo()
(> 和 < 不能正确翻译),这意味着如果您运行帐户 1 的搜索并且您要求查询返回 1000 个结果,但帐户 1 只有 600 个结果,最后 400 个结果将是帐户 10(词汇上的下一个帐号)。因此,您需要明智地对待如何处理结果。
如果您用前导 0 填充帐户 ID,您可以执行类似的操作(此处也有伪代码)
ctx.PartionKey > "TextCache_0000000001"
&& ctx.PartitionKey < "TextCache_0000000002"
&& ctx.RowKey > "123465798"
还需要记住的是,对 Azure 表的查询按照 PartitionKey
然后 RowKey
的顺序返回结果。因此,在您的情况下,没有 ParentMessageId
的消息将在具有 ParentMessageId
的消息之前返回。如果您永远不会通过 ParentMessageId
查询此表,我会将其移至属性。
如果 TextCache_
只是一个字符串常量,则它不会通过包含在 PartitionKey
中来添加任何内容,除非这在返回时对您的代码确实有意义。
虽然您的第二个查询将运行,但我认为它不会产生您想要的结果。如果您想要按 DateOfMessage
顺序排列前十行,那么它将不起作用(请参阅我上面关于排序顺序的观点)。如果您按原样运行此查询,并且帐户 1 有 11 条消息,它将仅返回与帐户 1 相关的前 10 条消息,无论帐户 2 是否有较早的消息。
虽然尝试最大程度地减少您使用的事务数量是一种很好的做法,但不必太担心。运行工作人员/网络角色的成本将使您的交易成本相形见绌。 1,000,000 笔交易将花费您 1 美元,这低于运行一个小型实例 9 小时的成本。
关于performance - Azure 表存储 - 选择在查询之间使用的 PartitionKey 和 RowKey,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5864512/