【问题标题】:How to enforce global uniqueness in a User table in CosmosDB如何在 CosmosDB 中的用户表中强制执行全局唯一性
【发布时间】:2020-05-30 14:49:59
【问题描述】:

我需要创建一个至少如下所示的User 表:

public class User
{
  public Guid Id {get; set;}
  public string Username {get; set;}
  public string EmailAddress {get; set;}
  public DateTime CreatedOn {get; set;}
}

我目前正在将所有数据写入CosmosDB (SQL API)。问题是我需要为所有用户的UsernameEmailAddress 添加唯一索引策略。由于CosmosDB 的设计考虑了横向扩展,因此我需要对这个容器进行分区。如果这样做,我将无法跨分区强制执行唯一性。

目前,我的分区键是Id。如果我将分区键更改为UsernameEmailAddress,我担心更改这些字段可能会导致用户被删除(例如,如果用户名属于不同的分区,删除旧用户名和插入新用户名将是两个单独的事务,这意味着没有原子性。)。

对于这个问题有没有我想不到的CosmosDB 解决方案?我可以将此部分移至SQL Server,但随着时间的推移,我最终会维护一张大桌子。此外,由于我使用 Azure Functions 进行服务器处理,因此附带 EF DLL 会使应用程序变得不必要地大。

【问题讨论】:

  • 您预计有多少用户?你不能把所有用户放在一个分区中吗?
  • 这取决于应用程序的成功程度。一个分区可容纳 20 个演出。如果一切顺利,我预计将来我需要的容量会比这个容量多得多。现在,我将所有内容都保存在 SQL Server 中,但我不喜欢 EF dll 使我的无服务器应用程序变得太大。
  • 另一个想法 - 您可以将电子邮件地址的域设置为 PartitionKey 吗?在这种情况下,所有 gmail 用户将进入一个分区,所有 hotmail 用户将进入另一个分区。
  • 我认为这会导致分区策略不佳,因为超过一半的电子邮件是 gmail。理想情况下,分区键应该平均分配以实现高吞吐量(因此我使用了Guid)。
  • 使用 Guid,每个分区只有一个用户。这也是不可取的:)。

标签: sql-server azure azure-functions azure-cosmosdb


【解决方案1】:

创建一个合成的partitionKey 属性并为其分配一个值,例如partitionKey:users_list。在那里您可以保留所有用户id'semails

{
   id: guid,
   email: user@whatever.com,
   partitionKey: "users_list"
}

创建一个注册新用户的存储过程,并在保存用户之前检查“users_list”分区中不存在具有相同电子邮件地址的其他用户。

如果您的文档大小为 1kb(我认为没有理由更大),那么您的分区最多可以容纳 2000 万用户。如果您需要更多,很容易使这个分区键细化,但仍然确保您将所有用户保留在非常少量的分区中。就像,5 个分区给你 1 亿用户。 例如,您可以将partitionKey 按时间、世界地区、起始字母以及任何您认为合适的粒度...

【讨论】:

    【解决方案2】:

    制作UserName_EmailAddress的合成分区键,它将是唯一的。

    【讨论】:

    • 如果您不想更改主容器的分区,您可以在一个单独的容器上执行此操作,该容器充当“全局索引”,强制执行唯一性并通过 (UserName) 提供优化的 ID 查找,电子邮件地址)。
    • @DavidBrowne-Microsoft,如果我达到我认为设置为 20 GB 的分区限制怎么办? MS 是否会通过支持票证等方式增加此需求限制?
    • 马克,我需要允许用户随意更改他们的用户名和电子邮件地址。更改分区键是一个两步的过程,而不是原子的(假设使用了两个不同的逻辑分区)。
    • @user246392 这是一个完全不同的问题。但基本上,1)选择一个分区键,这样就永远不会发生,或 2)在已满时替换逻辑分区的旧文档,或 3)在分区键中添加后缀,以便在已满时将数据分布在多个逻辑分区上。跨度>
    • 是的,这是您在必须管理客户端一致性方面需要做出的权衡。我也会使用墓碑标志而不是删除,因为它允许您回滚。
    猜你喜欢
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 2021-01-06
    相关资源
    最近更新 更多