当用户容器将 userId 作为分区键时,需要唯一的用户名

Require unique username when Users container has userId as partition key

我以这篇文章为例 https://docs.microsoft.com/en-us/azure/cosmos-db/how-to-model-partition-example 使用用户容器,用户 ID 和用户名以及分区键作为用户 ID。

{
    "id": "54c7da13-f4b8-4668-90dc-7c1aa968a73e",
    "userId": "54c7da13-f4b8-4668-90dc-7c1aa968a73e",
    "type": "user",
    "username": "jeffw"
}

在我的创建用户页面中,我想在添加新用户之前确保用户名是唯一的。我尝试了预触发器,但发现“您不能 运行 存储过程或触发器跨多个逻辑分区。”我如何确保在创建用户时他们选择了唯一的用户名?我想我可以将分区键更改为用户名,但为什么文章使用 userId 而不是?


解决方案

查看@mark-brown 的回答。

在用户容器和 /username 上创建一个唯一键:

await database.Database.DefineContainer(name: "Users", partitionKeyPath: "/userId")
                            .WithUniqueKey().Path("/username").Attach()
                            .CreateIfNotExistsAsync();

然后尝试创建一个用户 ID 为“unique_username”的新用户,并尝试创建新的用户名:

{
    "id": "06af2937-4677-4d27-a167-5517aa6d0ffd",
    "userId": "unique_username",
    "type": "unique_username",
    "username": "jeffw"
}

await _usersContainer.CreateItemAsync(uniqueUser, new PartitionKey("unique_username"));

如果用户名已经存在,这将 return 冲突状态。示例在这里 https://github.com/jwidmer/AzureCosmosDbBlogExample/blob/master/BlogWebApp/Services/BlogCosmosDbService.cs

将分区键更改为用户名无济于事,因为您的容器中可以有该值的倍数。一种方法是创建一个新分区,在其中为每个用户名存储一个唯一实例,并在容器上使用唯一索引(唯一索引在逻辑分区中是唯一的)。

创建一个新类型 = "unique_user" 和一个 userId = "unique_user"。然后在注册时使用新用户名添加该类型的新记录。这应该可以让您获得数百万用户而不会超过 20GB 的限制。然后在创建新用户时使用 "unique_user" 类型和带有新用户名的 id 在容器上插入。如果您得到 201,则使用 type= "user" 和其余用户数据进行另一次插入。

希望对您有所帮助。

您可以设置一个索引policy for unique values