定义唯一键约束,条件ally适用于同一容器/分区中的不同文档。

huangapple go评论57阅读模式
英文:

Define unique key constraints that conditionally apply to different documents within the same container/partition

问题

以下是翻译好的部分:

"给定以下存储在相同容器和分区中的文档,其中 Type 属性表示文档的类型(DocumentADocumentB):

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; }
}

是否可以创建 唯一键约束,仅适用于 DocumentADocumentB

例如,是否可以在 DocumentAName 属性上创建一个唯一键约束,以及在 DocumentBValue 属性上创建另一个唯一键约束?"

英文:

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同时出现了NameValue会怎么样?

为什么要强制将具有不同需求的文档放入同一个容器中?

如果真的需要唯一约束,那么您可以通过只使用**共享吞吐量数据库并拥有多个容器**来同时满足需求,即通过共享分区键、唯一约束以及可能在通用结构部分上的主要索引进行区分。这还具有更精细的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 作为分区键。唯一键受其分区的限制。

分区键与唯一键的组合确保了容器范围内项的唯一性。

Microsoft 文档

英文:

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.

Microsoft docs

huangapple
  • 本文由 发表于 2023年5月30日 02:20:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76359567.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定