我目前使用三种方法,具体取决于我的需要:
事务性
我将正向和反向关系存储在同一个分区上...这意味着每个实体都在同一个分区上(即这种方法受单个分区的速率限制),但这意味着您可以使用批处理事务来同时插入正向和反向关系,这意味着你知道它们永远是正确的。
public class OrganisationInvite : TableEntity
{
// Partition Id - string.Empty
// Row Id - "Invite_" + OrangisationId + "_" + UserId
public string Role { get; set; }
public DateTime Expiry { get; set; }
}
public class OrganisationRequest : TableEntity
{
// Partition Id - string.Empty
// Row Id - "Request_" + UserId + "_" + OrganisationId
public string Role { get; set; }
public DateTime Expiry { get; set; }
}
要查询,我使用t.RowKey.StartsWith("Request_...") 或t.RowKey.StartsWith("Invite_..."),具体取决于我是否要获取用户/组织邀请列表。
我想这在数据非常关键时最好使用。
最终一致性
我为这两个表提供了所有属性,但它们位于不同的分区上,这为您提供了出色的可伸缩性,但您丢失了事务。我使用消息队列来更新反向关系以匹配正向关系,因此最终数据将匹配。 (但有一段时间可能不会)。
// Assume both in the same table, thus the prefix on partition
public class OrganisationInvite : TableEntity
{
// Partition Id - "Invite_" + OrangisationId
// Row Id - UserId
public string Role { get; set; }
public DateTime Expiry { get; set; }
}
public class OrganisationRequest : TableEntity
{
// Partition Id - "Request_" + UserId
// Row Id - OrganisationId
public string Role { get; set; }
public DateTime Expiry { get; set; }
}
要查询,我使用t.PatitionKey == "Request_..." 或t.PatitionKey == "Invite_...",具体取决于我是否想要获取用户/组织邀请列表。也许您会将其中之一视为“事实来源”,因此当用户确实接受邀请时,您会查找“事实来源”并赋予用户该角色等。
这是最具可扩展性的解决方案,如果您在其上使用缓存,则尤其有意义。
事实来源
在这种情况下,我只给出一个实体的属性,而另一个实体只有反向关系的键。您可以将实体添加到最长或查询最多的列表中......在这种情况下,我会说它是一个组织的邀请。与最终一致性方法一样,您可以将反向关系排队以添加反向实体。此方法为您提供完整的数据一致性,除非您添加新关系(因为在创建反向关系之前有一点时间),并且具有高度可扩展性 - 虽然读取反向列表的成本更高。
// Assume both in the same table, thus the prefix on partition
public class OrganisationInvite : TableEntity
{
// Partition Id - "Invite_" + OrangisationId
// Row Id - UserId
public string Role { get; set; }
public DateTime Expiry { get; set; }
}
public class OrganisationRequest : TableEntity
{
// Partition Id - "Request_" + UserId
// Row Id - OrganisationId
}
您可以使用t.PatitionKey == "Invite_..." 轻松查询正向关系。但是,这种反比关系并非微不足道。您必须使用t.PatitionKey == "Request_..." 进行查询并创建n 个并行调用来获取每个项目的数据转发数据(在这种情况下使用在反向关系的RowKey 中找到的组织ID)。如果该项目不存在,则不要将其添加到最终列表中。这可确保如果组织更改其角色,例如用户将在下一次点击时看到此更改。
我认为如果很少使用反向关系并且数据是最新的至关重要(我在想用户权限等?),这种方法很有用。