Azure Cosmos DB 中的唯一键约束Unique key constraints in Azure Cosmos DB

唯一键在 Azure Cosmos 容器中添加一个数据完整性层。Unique keys add a layer of data integrity to an Azure Cosmos container. 在创建 Azure Cosmos 容器时将创建唯一键策略。You create a unique key policy when you create an Azure Cosmos container. 使用唯一键可确保逻辑分区内一个或多个值的唯一性。With unique keys, you make sure that one or more values within a logical partition is unique. 此外,可以保证每个分区键的唯一性。You also can guarantee uniqueness per partition key.

使用唯一键策略创建容器后,该策略会根据唯一键约束的指定,阻止在逻辑分区中执行会导致重复的创建新项或更新现有项的操作。After you create a container with a unique key policy, the creation of a new or an update of an existing item resulting in a duplicate within a logical partition is prevented, as specified by the unique key constraint. 分区键与唯一键的组合可保证某个项在容器范围内的唯一性。The partition key combined with the unique key guarantees the uniqueness of an item within the scope of the container.

例如,假设某个 Azure Cosmos 容器使用电子邮件地址作为唯一键约束,并使用 CompanyID 作为分区键。For example, consider an Azure Cosmos container with email address as the unique key constraint and CompanyID as the partition key. 将用户的电子邮件地址配置为唯一键后,每个项将在给定的 CompanyID 中获得唯一的电子邮件地址。When you configure the user's email address with a unique key, each item has a unique email address within a given CompanyID. 无法创建具有重复电子邮件地址和相同分区键值的两个项。Two items can't be created with duplicate email addresses and with the same partition key value. 在 Azure Cosmos DB 的 SQL (Core) API 中,项存储为 JSON 值。In Azure Cosmos DB's SQL (Core) API, items are stored as JSON values. 这些 JSON 值区分大小写。These JSON values are case sensitive. 选择某个属性作为唯一键时,可以为该属性插入区分大小写的值。When you choose a property as a unique key, you can insert case sensitive values for that property. 例如,如果在 name 属性上定义了唯一键,则“Gaby”与“gaby”有所不同,你可以将两者都插入容器。For example, If you have a unique key defined on the name property, "Gaby" is different from "gaby" and you can insert both into the container.

若要创建具有相同电子邮件地址但不是相同名字、姓氏和电子邮件地址的项,请将其他路径添加到唯一键策略。To create items with the same email address, but not the same first name, last name, and email address, add more paths to the unique key policy. 还可以使用名字、姓氏和电子邮件的组合创建唯一键,而不是仅根据电子邮件地址创建唯一键。Instead of creating a unique key based on the email address only, you also can create a unique key with a combination of the first name, last name, and email address. 此键称为复合唯一键。This key is known as a composite unique key. 在这种情况下,给定的 CompanyID 中允许这三个值的每种唯一组合。In this case, each unique combination of the three values within a given CompanyID is allowed.

例如,容器可以包含具有以下值的项,其中每个项遵循唯一键约束。For example, the container can contain items with the following values, where each item honors the unique key constraint.

CompanyIDCompanyID 名字First name 姓氏Last name 电子邮件地址Email address
ContosoContoso GabyGaby DuperreDuperre
ContosoContoso GabyGaby DuperreDuperre
FabrikamFabrikam GabyGaby DuperreDuperre
FabrikamFabrikam IvanIvan DuperreDuperre
FabrkamFabrkam DuperreDuperre

如果你尝试使用上表中列出的组合插入另一个项,则会收到错误。If you attempt to insert another item with the combinations listed in the previous table, you receive an error. 该错误指示不符合唯一键约束。The error indicates that the unique key constraint wasn't met. 你会收到作为返回消息的 Resource with specified ID or name already existsResource with specified ID, name, or unique index already existsYou receive either Resource with specified ID or name already exists or Resource with specified ID, name, or unique index already exists as a return message.

定义唯一键Define a unique key

只能在创建 Azure Cosmos 容器时定义唯一键。You can define unique keys only when you create an Azure Cosmos container. 唯一键的范围限定为逻辑分区。A unique key is scoped to a logical partition. 在前面的示例中,如果基于邮政编码将容器分区,则每个逻辑分区中会出现重复项。In the previous example, if you partition the container based on the ZIP code, you end up with duplicated items in each logical partition. 创建唯一键时请考虑以下属性:Consider the following properties when you create unique keys:

  • 不能将现有容器更新为使用不同的唯一键。You can't update an existing container to use a different unique key. 换而言之,使用唯一键策略创建容器后,无法更改策略。In other words, after a container is created with a unique key policy, the policy can't be changed.

  • 若要为现有容器设置唯一键,请使用唯一键约束创建新容器。To set a unique key for an existing container, create a new container with the unique key constraint. 使用适当的数据迁移工具将数据从现有容器移到新容器。Use the appropriate data migration tool to move the data from the existing container to the new container. 对于 SQL 容器,请使用数据迁移工具来移动数据。For SQL containers, use the Data Migration tool to move data. 对于 MongoDB 容器,请使用 mongoimport.exe 或 mongorestore.exe 来移动数据。For MongoDB containers, use mongoimport.exe or mongorestore.exe to move data.

  • 一个唯一键策略最多可以包含 16 个路径值。A unique key policy can have a maximum of 16 path values. 例如,值可以是 /firstName/lastName/address/zipCodeFor example, the values can be /firstName, /lastName, and /address/zipCode. 每个唯一键策略可以具有最多 10 个唯一键约束或组合。Each unique key policy can have a maximum of 10 unique key constraints or combinations. 每个唯一索引约束的组合路径不得超过 60 字节。The combined paths for each unique index constraint must not exceed 60 bytes. 在前面的示例中,名字、姓氏和电子邮件地址共同构成了一个约束。In the previous example, first name, last name, and email address together are one constraint. 此约束使用 16 个可能路径中的 3 个。This constraint uses 3 out of the 16 possible paths.

  • 如果容器具有唯一键策略,则创建、更新和删除项时产生的请求单位 (RU) 费用要略高一些。When a container has a unique key policy, Request Unit (RU) charges to create, update, and delete an item are slightly higher.

  • 不支持稀疏的唯一键。Sparse unique keys are not supported. 如果缺少某些唯一路径值,这些值将被视为 null 值,并参与唯一性约束。If some unique path values are missing, they're treated as null values, which take part in the uniqueness constraint. 因此,若要符合此约束,只能有一个项为 null 值。For this reason, there can be only a single item with a null value to satisfy this constraint.

  • 唯一键名称区分大小写。Unique key names are case-sensitive. 例如,假设某个容器的唯一键约束设置为 /address/zipcodeFor example, consider a container with the unique key constraint set to /address/zipcode. 如果数据包含名为 ZipCode 的字段,则 Azure Cosmos DB 会插入“null”作为唯一键,因为 zipcodeZipCode 不同。If your data has a field named ZipCode, Azure Cosmos DB inserts "null" as the unique key because zipcode isn't the same as ZipCode. 由于区分大小写,无法插入包含 ZipCode 的其他所有记录,因为重复的“null”违反唯一键约束。Because of this case sensitivity, all other records with ZipCode can't be inserted because the duplicate "null" violates the unique key constraint.

后续步骤Next steps