Warm tip: This article is reproduced from serverfault.com, please click

azure cosmosdb-如何在Cosmos DB中具有全局(跨整个容器)唯一约束?

(azure cosmosdb - How can I have a globally (across entire container) unique constraint in Cosmos DB?)

发布于 2020-11-27 16:17:38

假设我要存储如下所示的数据

type Person = {
    Name:string
    PassportNumber:string
}

type PolicyStatus =
    |SaleInProgress
    |PolicyActive
    |Cancelled

type Policy = {
    PincipalPerson: Person
    PolicyDependents: Person list
    PolicyId:int
    PolicyState:PolicyStatus
}

(我将这些类型表示为F#记录,因为它们看起来很像json,但不要让这分散你的注意力)

我希望做到这一点,以便每个人都具有Policy独特性。例如,这意味着,如果某人是某项策略的负责人,那么他们也不能成为某项其他策略的依赖者。

因此,如果我将这些存储在一个Policy集合中,那么我认为没有办法指定家属和校长的联合应该具有唯一的护照ID,是吗?

如果我使用的是RDMS,则可以将人员保留在不同的表上,并且在Policy之间有一个外键,People在上具有唯一约束PassportNumber

那么,在Cosmos DB中惯用的“ NoSQL”方式是什么呢?

Questioner
Chechy Levas
Viewed
0
Mo B. 2020-11-28 23:46:25

没有方法可以直接在Cosmos DB中强制执行你所要求的唯一性约束,至少如果你按照建议的数据结构构造,则至少不能这样做。Cosmos DB支持的唯一性约束基于(全部)属性值(例如,名字+姓氏或PassportNumber)的组合,因此你无法查看值的数组。

如果你确实想在数据库级别上执行唯一性约束,并且愿意更改数据模型,请考虑将策略嵌入到person对象中:

type Person = {
  Name: string
  PassportNumber: string              // with uniqueness constraint
  IsPrincipalPerson: Nullable<bool>   // specifies if the person is principal or dependent
  PolicyId: Nullable<int>
  PolicyState: Nullable<PolicyStatus>
}

该模型的缺点是,如果你需要更改策略的状态,则必须在其中出现策略ID的所有人员对象中对其进行更改。因此,你也可以使用以下模型:

type Person = {
  Name: string
  PassportNumber: string              // with uniqueness constraint
  IsPrincipalPerson: Nullable<bool>   // specifies if the person is principal or dependent
  PolicyId: Nullable<int>             // refers to a policy object
}

type Policy = {
  PolicyId: int
  PolicyState: PolicyStatus
}

现在,几个人对象可以共享一个策略对象,但是唯一性约束仍然得到执行,因为每个人最多可以拥有一个策略(作为主体或从属)。缺点是你需要照顾好person.PolicyId自己的参照完整性,因为不支持外键关系。