假设我要存储如下所示的数据
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”方式是什么呢?
没有方法可以直接在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
自己的参照完整性,因为不支持外键关系。
谢谢。这个特定的项目可能是我第一次将NoSql数据存储用于严肃的项目。我正在努力了解好处。由于大多数RDMS都对json字段提供了本机支持,因此整个无模式参数将不适用。我能想到的唯一好处是大多数NoSql DB可以提供的水平可伸缩性。但是,如果我的用户数量很少,那么我真的看不到牺牲有用的约束的意义,而我可以摆脱RDMS。
公平地说,Cosmos DB在处理无模式JSON数据方面具有优于SQL Server的优势(特别是在性能方面),它具有对所有属性(包括嵌套和数组值)的自动索引功能。Cosmos DB还为基于键集的快速分页提供了良好的支持。但是,正如您所看到的,确实存在一些严重的缺点:没有外键,没有关系联接,没有读事务,没有读写事务,还没有部分更新(尚未),文档大小限制。我的团队不得不在客户端解决所有这些问题,这很痛苦。
此外,您在这两个唯一性约束
PrincipalPerson
和PolicyDependants
不那么容易在RDBMS中执行任意。在RDBMS中的唯一性约束很容易用一个
Person
独特的表PassportNumber
,并在国外Policy.Principal
,以Person
和抚养的映射表。但是,那么您必须处理阻抗不匹配的问题。尽管注意到了Cosmos的优势。