Azure 表存储 - 父子模式(自引用架构)
使用 Windows Azure 表存储
(WATS) 并尝试更新应用程序以使用 Azure。我读过很多文章,但不确定最好的方法,即在自引用模型中从父母到孩子。
即单个父消息可以有许多子子消息。在数据库模型中,它将是一个自引用表。
我如何最好地为 WATS
构建这个结构,以便当我进行查询“给我 10 个父记录”时,它还将返回属于父记录
的 所有子消息...消息/子消息如下。我尝试将 PK 和 RK 定义如下:
public class TextCacheEntity : AzureTableEntity // custom table inherits AzureTableEntity
{
public override void GenerateKeys()
{
PartitionKey = string.Format("{0}_{1}_{2}", MessageType, AccountId.PadThis(), ParentMessageId );
RowKey = string.Format("{0}_{1}", DateOfMessage.Ticks.ReverseTicks(), MessageId);
}
public string MessageType { get; set; }
public int AccountId { get; set; }
public DateTime DateOfMessage { get; set; }
public string MessageId { get; set; }
public string ParentMessageId { get; set; }
// other properties...
}
我想到了一种实现,以便子消息存储parentMessagesId,而父parentMessageId 将为空。
模式将是
获取父消息
.Where(o => o.ParititionKey == "Parent_000000000000001_").Take(10)
获取子消息。迭代所有父消息并使用并行 for 循环
.Where(o => o.ParititionKey == "Child_000000000000001_" + ParentMessageId)
但问题是这将导致 11 次查询!
Using Windows Azure Table Storage
(WATS) and trying to update the app to use Azure. I've read many articles, and am not sure on the best approach for this, that is parent to child in a self referencing model.
ie a single parent message could have many child sub-messages. In a DB model, it would be a self referencing table.
How would I best structure this for WATS
so that when I make a query "Give me 10 parent records", it will also return all the child-messages belonging to the parent...
The entity of the message / submessage as below. I've tried to define the PK and RK as below:
public class TextCacheEntity : AzureTableEntity // custom table inherits AzureTableEntity
{
public override void GenerateKeys()
{
PartitionKey = string.Format("{0}_{1}_{2}", MessageType, AccountId.PadThis(), ParentMessageId );
RowKey = string.Format("{0}_{1}", DateOfMessage.Ticks.ReverseTicks(), MessageId);
}
public string MessageType { get; set; }
public int AccountId { get; set; }
public DateTime DateOfMessage { get; set; }
public string MessageId { get; set; }
public string ParentMessageId { get; set; }
// other properties...
}
I thought of an implementation so the child messages store the parentMessagesId, and the parent parentMessageId would be empty.
The pattern would then be
Get the parent messages
.Where(o => o.ParititionKey == "Parent_000000000000001_").Take(10)
Get the child messages. Iterate through all the parent messages and using a parallel for loop
.Where(o => o.ParititionKey == "Child_000000000000001_" + parentMessageId)
But the problem is that this will result in 11 queries !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请参阅 Scott Densmore 的示例:
http://scottdensmore.typepad.com/blog/2011/04/multi-entity-schema-tables-in-windows-azure.html
See this example by Scott Densmore:
http://scottdensmore.typepad.com/blog/2011/04/multi-entity-schema-tables-in-windows-azure.html
您可以通过对两者使用相同的 PK 来实现此目的。这样做有几个原因,但一个好的原因是您还可以同时向父级和子级发出批处理命令并实现一种一致的事务。此外,当它们在同一个表中共享相同的 PK 时,这意味着它们将被放在一起并从同一分区提供服务。您不太可能使用延续令牌(但您仍然应该期待它们)。要区分父级和子级,您可以添加属性或使用 RowKey。
唯一的技巧(以及您已经拥有的模型)是,如果父级和子级不是相同的 CLR 类型,您将在 WCF DataServices 中遇到序列化问题。当然,您可以通过创建同时具有子属性和父属性的 uber-CLR 类型来解决此问题,或者您可以使用 ReadingEntity 事件覆盖序列化并自行处理。
无论如何,对孩子和父母使用相同的 PK。然后,当您搜索 PK 范围时,您总是会立即返回父母和孩子(如果您愿意,您可以使用Where子句谓词进行区分)。
You can do this by using the same PK for both. There are a couple reasons to do this, but one good one is that you can then also issue batch commands for parent and children at once and achieve a type of consistent transaction. Also, when they share the same PK within the same table, it means they are going to be colocated together and served from the same partition. You are less likely to continuation tokens (but you should still expect them). To differentiate between parent and children you can either add an attribute or use the RowKey perhaps.
The only trick to this (and the model you already ahve), is that if the parent and children are not the same CLR type, you will have issues with serialization in WCF DataServices. You can fix this of course by creating an uber-CLR type that has both child and parent properties or you can override serialization with the ReadingEntity event and handle it yourself.
Anyhow, use the same PK for both children and parent. Then when you search PK ranges you will always get parents and children returned at once (you can discriminate with a Where clause predicate if you wish).