对于典型的增删改查(CRUD)应用程序,DynamoDB推荐的索引模式是什么?

11 浏览
0 Comments

对于典型的增删改查(CRUD)应用程序,DynamoDB推荐的索引模式是什么?

我一直在阅读一些DynamoDB索引文档,但它们让我更加困惑。让我们通过一个具体的例子来澄清一下。

我有一个简单的日历应用程序,其中有一个events表。这是我拥有的列:

id: guid,
name: string,
startTimestamp: integer,
calendarId: guid(传统关系型数据库模型中的外键),
ownerId: guid(传统关系型数据库模型中的外键)

我想执行以下查询:

  • 按ID获取事件
  • 获取所有calendarId = xownerId = y的事件
  • 获取所有startTimestamp在x和y之间calendarId = z的事件

DynamoDB文档似乎强烈建议避免将事件的ID用作这里的分区/排序键,那么推荐的模式是什么?

0
0 Comments

这个问题的出现是因为在使用DynamoDB时,想要找到一个适合典型CRUD应用程序的推荐索引模式。下面是解决这个问题的方法。

为了解决这个问题,可以采取以下步骤:

1. 使用GSI(全局二级索引)的分区键进行查询,并在ownerId上添加一个条件。

2. 但是,这种方法并不可靠,因为DynamoDB有一个1MB的读取限制,这使得该方法不可靠。

3. 当查询的数据量超过1MB时,DynamoDB只会返回前1MB的结果,并且会截断剩余的数据。

4. 可以点击这里了解更多详情。

根据上面的解释,可以得出以下结论:

如果要查询的数据量超过1MB,并且希望通过添加条件来筛选结果,那么这种方法是不可靠的。因此,需要考虑其他解决方案,以满足查询的需求。

0
0 Comments

这个问题的出现是因为在使用DynamoDB时,每个人都会面临这个问题,无论是刚开始使用还是有经验的用户。

首先,我们需要考虑DynamoDB的定价和吞吐量。对于数据存储,每个月需要支付0.25美元/GB。对于写入吞吐量,每个月需要支付0.47美元/写入吞吐量单位(WCU)。对于读取吞吐量,每个月需要支付0.09美元/读取吞吐量单位(RCU)。吞吐量是指您在表上的WCUs和RCUs的数量。您需要在表上预先指定吞吐量,表上的写入和读取操作的数量受到吞吐量限制。支付更多费用,您可以每秒执行更多的读写操作。关于DynamoDB如何分区表的详细信息可以在这个答案中找到。

接下来,我们需要考虑表的分区。表必须有一个主键,主键必须有一个哈希键(也称为分区键),还可以选择一个排序键(也称为范围键)。DynamoDB根据哈希键的值创建分区。在分区键值内,如果指定了排序键,则数据按排序键进行排序。

数据访问方面,如果您有确切的主键(哈希键和排序键,如果有的话),则可以使用GetItem立即访问项目。如果您有多个要获取的项目,可以使用BatchGetItem。DynamoDB只能通过两种方式“搜索”数据。Query只能从一个分区中获取数据,因为它使用分区键(和可选的排序键),所以查询速度很快。Scan总是评估表中的每个项目,因此在大表上通常速度较慢且不可扩展。

在吞吐量分布方面,DynamoDB将所有已购买的吞吐量均匀分布到所有表分区上。假设您的表上有10个WCUs和10个RCUs以及5个分区,那么每个分区将有2个WCUs和2个RCUs。如果您均匀访问每个分区,您将能够使用所有已购买的吞吐量。但是,如果您只访问一个分区,那么您购买的10个WCUs和RCUs只能使用2个。您的表速度将比您预期的要慢得多。一种解决方法是购买更多的吞吐量,但这对大多数工程师来说可能并不令人满意。

根据上述内容,我们知道我们希望设计一个表,使每个分区都能被均匀访问。然而,根据我的经验,人们过于关注这一点,在阅读我刚刚链接的文章后可能并不令人惊讶。

我喜欢参考最佳实践指南。特别是当它说“用户ID是一个很好的分区键,只要许多用户定期访问您的应用程序”。这实际上是错误的,表的大小是无关紧要的。这是在直观访问和均匀访问之间的一个平衡,但是我想说的是,如果您刚开始使用DynamoDB,正确的答案可能是基于直观访问来设计您的表。在成功完成此操作后,考虑均匀访问和热分区,但只需记住访问不必完全均匀。有各种设计模式可以实现直观和均匀访问,但对于刚开始使用DynamoDB的人来说,这可能会变得复杂,并且在许多情况下,可能会阻止人们使用DynamoDB,如果他们过于关注均匀访问的想法。

大多数应用程序都有用户。对于大多数应用程序的查询,最常见的查询是根据用户获取数据。因此,对于大多数应用程序的主分区键,第一个选项通常是用户ID。只要没有一些非常高点击量的用户和许多从不登录的用户,这是可以的。

另一个提示是,如果您的表名为vegetables,主分区键可能是vegetable id。如果您的表名为shoes,主分区键可能是shoe id。

大多数应用程序对于每个用户(或蔬菜或鞋子)都有很多项。主键必须是唯一的。一个很好的选择通常是添加一个日期范围(排序)键,比如项的创建日期时间。这样可以按创建日期对用户分区内的项进行排序,并为每个项提供唯一的复合主键(即哈希键+排序键)。也可以使用生成的UUID作为范围键,您将不使用其提供的排序功能,但仍然可以拥有多个用户的多个项并使用查询函数。

索引不是解决办法。索引具有自己的吞吐量和分区,与构建索引的表分开。可以将索引想象成一个全新的表,基本上就是这样。索引不能解决分区访问不均匀的问题。

最后,您的模式应该是:

主键:

哈希键:事件ID

排序键:无

全局二级索引:

哈希键:日历ID

排序键:开始时间戳

假设事件ID是均匀访问的,那么它将是一个很好的哈希键。您需要描述数据的分布情况才能进一步讨论此问题。其他因素还包括您希望查询的速度以及您愿意支付的费用(例如,二级索引是昂贵的)。

查询示例:

- 根据ID获取事件:使用事件ID进行GetItem操作。

- 获取所有日历ID为x且所有者ID为y的事件:通过全局二级索引的分区键进行查询,并添加ownerId的条件。

- 获取开始时间戳在x和y之间且日历ID为z的所有事件:通过全局二级索引的分区键进行查询,并添加范围键的条件。

以上是关于DynamoDB典型的CRUD应用程序推荐的索引模式。

0