CosmosDB/DocumentDB 分区,在同一集合中具有多种类型



据我所知,团队的官方建议是将所有数据类型放入单个集合中,这些集合在文档中具有类似于type=someType字段以区分类型。

现在,如果我们假设大型数据库具有分区,其中不同的对象类型可以是:

  1. 完全不同的字段(因此没有用于分区的公共字段)
  2. 相关(通过参考)

如何组织事物,使应该放在一起的东西最终位于同一分区中?

例如,假设我们有:

用户

博客帖子

博客帖子评论

如果我们将它们存储为单独的类型,type=user|blogPost|blogPostComment,在同一集合中,我们如何确保用户、他的博客文章和所有相应的评论最终位于同一分区中? 是否有一些最佳实践?

[更新] 你能完全避免跨分区查询吗?这应该是一个目标吗?或者你只是试图最小化它们? 例如,您可以为 99% 的案例/查询完美地分区数据,但随后您需要一些仪表板来显示所有数据的聚合。这是你只是接受为不可避免的事情并试图最小化,还是有可能完全避免它?

我在关于 Cosmos 的其他类似问题中对此进行了广泛的讨论。

基本上,在单个 Cosmos 集合中处理许多不同的逻辑实体类型时,最简单的选择是在所有文档上放置一个通用(或抽象,如你所说的)分区键。此时,应用程序关注的是确保在运行时选择适当的值。我通常将此文档属性命名为partitionKeyroutingKey或类似的东西。

在设计最佳查询效率时,这一点非常重要,因为您选择的分区键可能会对查询和吞吐量性能产生巨大影响。像这样的通用键可让您设计数据的最佳存储,因为它有利于您正在构建的任何应用程序。

即使是像tenant这样的东西也没有意义,因为不同的租户可能具有截然不同的数据大小和访问模式。相反,可以在运行时将tenantId作为分区键的一部分作为复合的一部分包含在内。

更新: 对于某些查询模式,可以完全在单个分区中提供它们。不过,如果事情最终交叉分裂,这绝对不是世界末日。系统仍然很快。如果可能,限制给定查询需要接触的分区数量是理想的,但您永远不会 100% 摆脱它。

分区应保存与预期增长的组相关的数据,例如,将许多文档分组的租户(如您所提到的,可以是不同类型的) 因此,此实例中的分区键应该是 TenantId。分区更多的是与组相关的数据,而不是数据类型。如果数据与用户相关,那么您可以使用UserId,但是许多用户可能会对相同的帖子发表评论,因此除非对用户信息进行一些非规范化,否则它似乎不是分区键的良好候选者,因此它不必直接与其他用户相关。如果这有意义?

最新更新