据我所知,团队的官方建议是将所有数据类型放入单个集合中,在文档中使用type=someType
字段来区分类型。
现在,如果我们假设大型数据库具有不同对象类型的分区:
如何组织事物以使那些应该在一起的东西最终在同一个分区中?
例如,假设我们有:
用户
博文
BlogPostComment
如果我们将它们作为单独的类型与type=user|blogPost|blogPostComment
一起存储在同一个集合中,我们如何确保用户,他的博客帖子和所有相应的评论最终都在同一个分区中?
对此有一些最佳实践吗?
[UPDATE] 你能完全避免跨分区查询吗?这应该是一个目标吗?或者你只是尽量减少它们? 例如,您可以完美地对99%的案例/查询进行数据分区,但是您需要一些仪表板来显示来自所有数据的聚合。这是你接受的不可避免的事情,并尽量减少或完全避免它吗?
答案 0 :(得分:3)
I've written about this somewhat extensively in other similar questions regarding Cosmos.
基本上,当在单个Cosmos集合中处理许多不同的逻辑实体类型时,最简单的选择是在所有文档上放置泛型(或抽象,如您所指的)分区键。此时,应用程序的关注点是确保在运行时选择适当的值。我通常将此文档属性命名为partitionKey
,routingKey
或类似的东西。
在设计最佳查询效率时,这一点非常重要,因为您选择的分区键可能会对查询和吞吐量性能产生巨大影响。像这样的通用密钥可以让您设计最佳的数据存储,因为它有利于您正在构建的任何应用程序。
即使像tenant
这样的东西也没有意义,因为不同的租户可能会有截然不同的数据大小和访问模式。相反,您可以在运行时将tenantId
作为分区键的一部分包含在一起作为一种复合。
更新: 对于某些查询模式,可以完全从单个分区中提供它们。如果事情最终会跨越分区,那绝对不是世界末日。系统仍然很快。如果可能的话,限制针对给定查询需要触摸的分区数量是理想的,但是您永远不会在100%的时间内远离它。
答案 1 :(得分:2)
分区应该包含与预期会增长的组相关的数据,例如租户将对许多文档进行分组(可以是您提到的不同类型)因此,此实例中的分区键应该是TenantId 。分区更多地是关于与组相关的数据而不是数据类型。如果数据与用户相关,那么您可以使用UserId,但是许多用户可能会对相同的帖子发表评论,因此它看起来不是分区键的合适候选者,除非用户有一些非规范化信息,所以它必须直接与其他用户联系..如果这是有道理的?