Cosmos数据库用户ID /电子邮件作为分区键

时间:2019-06-26 18:24:16

标签: azure-cosmosdb

关于为存储用户数据的分区键选择最佳(语义)值,我有一个难题。

用户文档具有: -ID(GUID) -电子邮件(例如用于登录) -个人资料数据

主要有2种查询类型:

  1. id查找用户(大多数查询)
  2. 通过email查找用户(登录和一些管理员查询)

我想避免跨分区查询。

如果我为id(综合字段)选择partitionKey,则登录查询将是跨分区的。 另一方面,如果我选择email,那么如果用户曾经更改过电子邮件-这是一个问题。

我的想法是在集合中引入新类型。像这样:

userId: guid,
userEmail: “email1”,
partitonKey: “users-mappings”

然后我可以将User文档本身设置为:

id: someguid,
type: “user”,
partitionKey: “user_someguid”,
profileData: {}

以这种方式,当用户登录时,我首先通过email检查映射类型/分区,获取guid,然后通过User检查实际的guid文档。

此外,通过这种方式可以更改电子邮件而不会影响分区。

这是有效的方法吗?有什么问题吗?我想念什么吗?

2 个答案:

答案 0 :(得分:1)

您的问题没有标准答案。我认为,名为mapping type的解决方案会导致两个查询效率低下。选择分区密钥始终是平衡利弊的过程。请参阅官方文档中的guidance

根据您的描述:

  

1。按ID查找用户(大多数查询)

     

2。通过电子邮件查找用户(登录和一些管理员查询)

我建议您优先考虑最频繁的查询,即id

我的原因:

1.id不会轻易更改,相对稳定。

2。会话或cookie可以在登录后保存,因此与id相同的登录权限很少。

3.id是您最常查询的条件,因此不可能每次都跨越所有分区。

4。如果您确实担心登录性能,请不要忘记为email列添加indexing policy。这也可以提高性能。

答案 1 :(得分:1)

您已经知道,在查询Cosmos DB中,扇出应该是查询的最后一个选项,尤其是在诸如登录之类的大批量操作时。此外,使用大数据时,RU的成本将明显更高。

在Cosmos DB SQL API中,一种模式是使用合成分区键。您可以通过将ID和写入时的电子邮件连接起来来组成合成分区键。此模式适用于提供灵活性的众多查询方案。

类似这样的东西:

{
  "id": "123",
  "email":"joe@abc.com",
  "partitionKey":"123-joe@abc.com"
}

然后在阅读时,执行以下操作:

SELECT  s.something
FROM    s
WHERE   STARTSWITH(s.partitionKey, "123")
        OR
        ENDSWITH(s.partitionKey, "joe@abc.com")

您还可以使用SUBSTRING()等...

使用上述方法,您可以通过用户的 id 电子邮件来搜索用户,并且仍然可以使用分区键的效率,从而最大程度地减少查询RU成本和优化性能。