我需要创建一个至少如下所示的User
表:
public class User
{
public Guid Id {get; set;}
public string Username {get; set;}
public string EmailAddress {get; set;}
public DateTime CreatedOn {get; set;}
}
我目前正在将所有数据写入CosmosDB
(SQL API(。问题是我需要添加一个唯一的索引策略来Username
和EmailAddress
所有用户。由于CosmosDB
在设计时考虑了横向扩展,因此我需要对此容器进行分区。如果我这样做,我就无法跨分区强制实施唯一性。
目前,我的分区键是Id
。如果我将分区键更改为Username
或EmailAddress
,我担心更改这些字段可能会导致用户被删除(例如,如果用户名属于不同的分区,则删除旧用户名和插入新用户名将是两个单独的事务,这意味着没有原子性。
这个问题有没有我想不出的CosmosDB
解决方案?我可以将此部分移动到SQL Server
,但随着时间的推移,我最终会维护一张大桌子。此外,由于我使用Azure Functions
进行服务器处理,因此随 EF DLL 一起提供会使应用大小不必要地变大。
创建一个合成partitionKey
属性并为其赋值,例如partitionKey:users_list
. 在那里,您可以保持所有用户id's
和emails
:
{
id: guid,
email: user@whatever.com,
partitionKey: "users_list"
}
创建一个注册新用户的存储过程,并在保存用户之前检查"users_list"分区中不存在具有相同电子邮件地址的其他用户。
如果您的文档是 1KB(我认为没有理由更多(,那么您的分区最多可容纳 2000 万用户。 如果您需要更多,很容易使此分区键细化,但仍要确保将所有用户保留在非常少量的分区中。 例如,5 个分区为您提供 1 亿用户。 例如,您可以按时间、世界区域、开头字母以及您认为合适的任何内容进行partitionKey
粒度......
创建一个UserName_EmailAddress
的合成分区键,它将是唯一的。