简体   繁体   English

DynamoDB 创建唯一分区键

[英]DynamoDB creation of a unique partition key

Let's say I'm creating a DynamoDB table called Products that contains any number of items that a user could purchase.假设我正在创建一个名为Products的 DynamoDB 表,其中包含用户可以购买的任意数量的项目。 An admin should be able to access a front end page to enter product details, send the details to a Lambda, which creates a new Product in the Products table.管理员应该能够访问前端页面以输入产品详细信息,将详细信息发送到 Lambda,它会在Products表中创建一个新产品。

I understand that a partition key should be highly distributed to avoid hot partitions, so I was looking to use a productId (which would be a number) as the partition key.我知道分区键应该高度分布以避免热分区,所以我希望使用productId (这将是一个数字)作为分区键。 My question is, if DynamoDB has no concept of auto-increment fields, how can I create a unique key as to not overwrite any item already in the table?我的问题是,如果 DynamoDB 没有自动增量字段的概念,我如何创建唯一键以不覆盖表中已有的任何项目? I would not expect an admin to have to input a unique number when creating an item.我不希望管理员在创建项目时必须输入唯一编号。 I am planning on using a sort key.我打算使用排序键。

What you are looking for is an anti-pattern in DynamoDB, the whole purpose of going NoSQL was to speed up database reads by eliminating the need to for locks which is required by auto-increment features.您正在寻找的是 DynamoDB 中的反模式,使用 NoSQL 的全部目的是通过消除自动增量功能所需的锁来加速数据库读取。

Have you considered using uuid ?您是否考虑过使用uuid

npm install uuid

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

Otherwise, I would recommend using a hybrid model where an RDS is needed to store your products list and generate a unique ID using auto-increment feature.否则,我建议使用混合 model,其中需要 RDS 来存储您的产品列表并使用自动增量功能生成唯一 ID。 You can then let the other lock-intensive data be stored in DynamoDB (EG. Transactions, Transaction Items).然后,您可以让其他锁密集型数据存储在 DynamoDB 中(例如 Transactions、Transaction Items)。

There are many tools to generate unique id values.有许多工具可以生成唯一的 id 值。 Personally, I recommend you look at KSUID which is a UID generator that has the nice extra characteristic it's naturally sorted by timestamp.就个人而言,我建议您查看 KSUID,它是一个 UID 生成器,具有很好的额外特性,它自然地按时间戳排序。 With a partition key (as in your case today) it doesn't matter, any UID will work, but for situations later where you use an ID in the sort key... if you're using a KSUID the values will be in timestamp order and you can pull out, for example, an item by id or the 10 most recent items, both off the same index.使用分区键(如您今天的情况)没关系,任何 UID 都可以使用,但对于稍后在排序键中使用 ID 的情况......如果您使用的是 KSUID,则值将在时间戳顺序,例如,您可以按 id 提取一个项目或 10 个最近的项目,两者都来自同一个索引。

https://github.com/segmentio/ksuid https://github.com/segmentio/ksuid

Several responses already mentioned how you can create a unique id - time based or random - to ensure that each new product gets a unique id.一些回复已经提到如何创建一个唯一的 id - 基于时间或随机 - 以确保每个新产品都获得一个唯一的 id。

One problem with this approach is that the product-adding operation is not idempotent , ie, if you do it twice (eg, because of some network problem), you'll add the same product twice.这种方法的一个问题是产品添加操作不是幂等的,即,如果您执行两次(例如,由于某些网络问题),您将添加两次相同的产品。 One way to fix this is to calculate the item's key as a hash function of the initial content of the product - this way, if you try to add the exact same product twice, you'll set both under the same key and only get one item, not two.解决此问题的一种方法是将项目的密钥计算为产品初始内容的 hash function - 这样,如果您尝试添加完全相同的产品两次,您将在相同的密钥下设置两者并且只得到一个项目,不是两个。

Finally, in some situations you have some mostly-unique way of defining a new key, which isn't always unique - perhaps some counter you can't fully trust to be concurrency-safe, the current time, and so on.最后,在某些情况下,您有一些最独特的方式来定义一个新的密钥,这并不总是唯一的——也许您不能完全相信某个计数器是并发安全的、当前时间等等。 You may want to use this key - but only if you can verify that some other concurrent process didn't beat you to using this key.您可能想要使用此密钥 - 但前提是您可以验证其他一些并发进程没有击败您使用此密钥。 Well, you can easily do this - you can use a conditional update to set the item but only if an item with this key doesn't yet exist.好吧,您可以轻松地做到这一点 - 您可以使用条件更新来设置项目,但前提是具有此键的项目尚不存在。 This can be done safely (with regards to concurrency).这可以安全地完成(关于并发)。 You can do this with a ConditionExpression like attribute_not_exists(p) or p <>:p (both conditions will fail if the item already exist, with p being the partition (and only) key in this example).您可以使用ConditionExpression来执行此操作,例如attribute_not_exists(p)p <>:p (如果项目已经存在,这两个条件都将失败,在此示例中p是分区(且唯一)键)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM