【问题标题】:DynamoDB creation of a unique partition keyDynamoDB 创建唯一分区键
【发布时间】:2022-02-01 00:26:06
【问题描述】:

假设我正在创建一个名为 Products 的 DynamoDB 表,其中包含用户可以购买的任意数量的项目。管理员应该能够访问前端页面以输入产品详细信息,将详细信息发送到 Lambda,后者会在 Products 表中创建一个新产品。

我知道分区键应该高度分布以避免热分区,因此我希望使用productId(将是一个数字)作为分区键。我的问题是,如果 DynamoDB 没有自动增量字段的概念,我如何创建唯一键以不覆盖表中已有的任何项目?我不希望管理员在创建项目时必须输入唯一编号。我打算使用排序键。

【问题讨论】:

    标签: database amazon-web-services nosql amazon-dynamodb


    【解决方案1】:

    有许多工具可以生成唯一的 id 值。就个人而言,我建议您查看 KSUID,它是一个 UID 生成器,具有很好的额外特性,它自然地按时间戳排序。使用分区键(如您今天的情况)没关系,任何 UID 都可以使用,但是对于稍后在排序键中使用 ID 的情况......如果您使用的是 KSUID,则值将在时间戳顺序,例如,您可以按 id 提取一个项目或 10 个最近的项目,两者都来自同一个索引。

    https://github.com/segmentio/ksuid

    【讨论】:

      【解决方案2】:

      您正在寻找的是 DynamoDB 中的反模式,采用 NoSQL 的全部目的是通过消除自动增量功能所需的锁来加速数据库读取。

      您是否考虑过使用uuid

      npm install uuid
      
      import { v4 as uuidv4 } from 'uuid';
      uuidv4(); // ⇨ '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'
      

      否则,我建议使用混合模型,其中需要 RDS 来存储您的产品列表并使用自动增量功能生成唯一 ID。然后,您可以让其他锁密集型数据存储在 DynamoDB 中(例如,事务、事务项)。

      【讨论】:

        【解决方案3】:

        已经有几个回复提到了如何创建唯一 ID(基于时间或随机)以确保每个新产品都获得唯一 ID。

        这种方法的一个问题是添加产品的操作不是幂等的,也就是说,如果你做了两次(例如,由于某些网络问题),你将添加相同的产品两次。解决此问题的一种方法是将项目的密钥计算为产品初始内容的散列函数 - 这样,如果您尝试添加完全相同的产品两次,您将在相同的密钥下设置两者并且只得到一个项目,而不是两个。

        最后,在某些情况下,您有一些最独特的方式来定义一个新的密钥,它并不总是唯一——也许某些计数器你不能完全相信它是并发安全的,当前时间,等等。您可能想要使用此密钥 - 但前提是您可以验证其他一些并发进程没有击败您使用此密钥。好吧,您可以轻松地做到这一点 - 您可以使用 条件更新 来设置项目,但前提是具有此键的项目尚不存在。这可以安全地完成(关于并发)。您可以使用ConditionExpression 来执行此操作,例如attribute_not_exists(p)p <> :p(如果项目已经存在,这两个条件都将失败,p 在此示例中是分区(也是唯一的)键)。

        【讨论】:

          猜你喜欢
          • 2021-05-30
          • 2020-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-23
          • 2020-08-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多