英文:
Define unique key constraints that conditionally apply to different documents within the same container/partition
问题
以下是翻译好的部分:
"给定以下存储在相同容器和分区中的文档,其中 Type
属性表示文档的类型(DocumentA
或 DocumentB
):
class DocumentA
{
public Guid Id { get; set; }
public Guid ParitionKey { get; set; }
public string Name { get; set; }
public string Type { get; set; }
}
class DocumentB
{
public Guid Id { get; set; }
public Guid ParitionKey { get; set; }
public int Value { get; set; }
public string Type { get; set; }
}
是否可以创建 唯一键约束,仅适用于 DocumentA
或 DocumentB
?
例如,是否可以在 DocumentA
的 Name
属性上创建一个唯一键约束,以及在 DocumentB
的 Value
属性上创建另一个唯一键约束?"
英文:
Given the following documents which are stored in the same container and partition where the Type
property denotes what the documents type is (DocumentA
or DocumentB
):
class DocumentA
{
public Guid Id { get; set; }
public Guid ParitionKey { get; set; }
public string Name { get; set; }
public string Type { get; set; }
}
class DocumentB
{
public Guid Id { get; set; }
public Guid ParitionKey { get; set; }
public int Value { get; set; }
public string Type { get; set; }
}
Is it possible to create unique key constraints that only apply to either DocumentA
or DocumentB
?
For example, could I create a unique key constraint on DocumentA
's Name
property and another for DocumentB
's Value
property?
答案1
得分: 2
根据另一个属性值有条件地应用唯一约束是不可能的,据我所知。
我会考虑以下替代方案:
是否需要在数据库级别强制唯一约束?
是否真的需要在每次数据修改操作上进行验证,以至于需要这个唯一约束?也许确实需要,而且这并不是一个巨大的负担,但在无模式架构的世界中,通常有许多约束不会在数据层面强制执行,而是在业务层面执行。与关系数据思维相反,在NOSQL中,通常更好的做法是保持存储层面简单(除了为性能提供有针对性的索引外),并且在创建/更新RU成本上节省可能在整体上更为重要。此外,更改唯一约束非常麻烦,因此拥有一个唯一约束需要您非常确定它能够适应每种文档类型的更改和新文档类型。例如,如果DocumentC
同时出现了Name
和Value
会怎么样?
为什么要强制将具有不同需求的文档放入同一个容器中?
如果真的需要唯一约束,那么您可以通过只使用**共享吞吐量数据库并拥有多个容器**来同时满足需求,即通过共享分区键、唯一约束以及可能在通用结构部分上的主要索引进行区分。这还具有更精细的RBAC访问控制、更精确的索引、更便宜的扫描、更好的命名、更易读的代码、更清晰的依赖关系等附加优势。
关于拥有太多容器的不足之处:
-
更加繁琐的管理
-
有一个限制(25?)可以放入相同的共享吞吐量数据库中的容器数量。
-
失去了跨“类型”查询的能力(例如“在X和Y之间创建的文档”等)
英文:
Applying unique constraints conditionally based on another property value is not possible, AFAIK.
I would consider instead:
Is the unique constraint required at DB-level?
Is it really so dangerous that you need to verify this on every data-modifying operation? Maybe it is, and it's not a huge burden, but quite often in the schema-less world there are many constraints not enforced on data layer, but in business layer. Contrary to relational-data mindset, it usually works better in NOSQL to keep the storage dumb (except having good targeted indexes for performance) and saving on create/update RU cost may matter more in the big picture.
Also, changing unique constraints is a PITA, so having one requires you to be really sure that it can accommodate every document type changes and new document types. For example, what if DocumentC
pops up with both Name
and Value
?
Why force documents with different requirements into the same container?
If the unique constraints are really-really needed, then you could have the cake and eat it too by just using shared-throughput database and have N containers instead, i.e. differentiated by shared partition key, unique constraints and perhaps main indexes on common structure parts. This has the additional benefits of more granular RBAC access control, more precise indexes, cheaper scans, better names, more readable code, clearer dependencies etc.
On the downsides of having too many containers:
- more cumbersome to manage
- there's a limit (25?) how many containers can be put into same
shared-throughput database. - loss of ability to query across "types" (for example "docs created between X and Y", etc)
答案2
得分: 1
据我所知,条件唯一约束不是一项功能,但您可以通过在路径'/Name'、'/Type'和'/Value'上使用复合唯一键来实现您的目标。
不支持稀疏唯一键。如果某些唯一路径值缺失,它们将被视为 null 值,这将参与到唯一性约束中。因此,只能有一个具有 null 值的项来满足此约束。
这将导致'/Name'或'/Value'中的一个为 null。在您的情况下,这正是您想要的。
小提醒:
我看到您正在使用 GUID 作为分区键。唯一键受其分区的限制。
分区键与唯一键的组合确保了容器范围内项的唯一性。
英文:
As far as I know, conditional unique constraints aren't a feature, but you could achieve your goal by using a composite unique key on the paths '/Name' and '/Type' and '/Value'
> Sparse unique keys are not supported. If some unique path values are missing, they're treated as null values, which take part in the uniqueness constraint. For this reason, there can be only a single item with a null value to satisfy this constraint.
This will resolve in either /Name of /Value being null. In your case, this is exactly what you want.
Little heads up:
I see you're using a GUID as partition key. Unique keys are limited to their partition.
> The partition key combined with the unique key guarantees the uniqueness of an item within the scope of the container.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论