繁体   English   中英

如何在同一个主键下创建多个 DynamoDB 条目?

[英]How to create multiple DynamoDB entries under the same primary key?

我正在为 Amazon Alexa 开发一项技能,我正在使用 DynamoDB 来存储有关用户最喜欢的对象的信息。 我想要数据库中的 3 列:

  1. Alexa 用户 ID
  2. Object
  3. 颜色

我目前将 Alexa userId 作为主键。 我遇到的问题是,如果我尝试向数据库中添加一个具有相同 userId 的条目,它会覆盖那里已有的条目。 我如何允许用户通过多行在数据库中拥有与其关联的多个对象? 我希望能够通过 userId 查询数据库并接收他们指定的所有对象。

如果我为每个条目创建一个唯一的 id,并且有多个用户,我不可能知道要查询的 id 以获取活动用户的对象。

这里有两个主要选项,它们有不同的优缺点

首先,您可以使用复合主键 它允许您在表中具有1对N的关系

在你的情况下,它可以是这样的:

AlexaId - 分区键

对象 - 排序键

它允许您获取给定AlexaId的所有对象。

此方法的局限性:

  • 您可以使用相同的分区键存储最多10GB的数据,这意味着同一AlexaId的所有项目的大小总和限制为10GB。

  • 以这种方式处理多个项目不是原子的 DynamoDB本身不支持事务,因此在处理项目时不能具有原子性。 您可以将DynamoDB事务库用于Java ,但DynamoDB中的事务 非常昂贵

另一种选择是将这些对象存储在项目本身中。 在常规SQL数据库中,您只能在DynamoDB中的行中存储标量值,每个项目都可以包含复杂类型,例如集合,列表和嵌套对象。

您可以在此处阅读有关DynamoDB数据类型的更多信息。

有了这个,你可以有这样一个表:

AlexaId - 分区键

对象 - 列表或集合或地图

这种方法的优点:

  • DynamoDB本身支持每个项目的原子性。 您可以执行项目的原子更新,甚至可以进行乐观锁定

此方法的局限性:

  • 项目大小限制为400KB,因此您无法在其中存储大量数据。

DynamoDB是一个类似NoSQL的文档数据库或键值存储; 这意味着,您可能需要以不同于RDBMS的方式考虑您的表。 根据我的理解,对于每个用户,您希望在对象列表中存储有关其首选项的信息; 因此,请保持主键简单,即用户ID。 然后,有一个单一的“列”,您可以在其中存储所有首选项。 这可以是元组(对象,颜色)的列表,也可以是唯一的{object:color}字典。

当您浏览Web UI中的项目时,它会将这些复杂的数据结构显示为类似json的文档,您可以随意展开它们。

如果Alexa ID + Object的组合是唯一的(非重复的),那么您应该使用复合主键配置表:

  • 分区键= Alexa ID
  • 排序键=对象

然后,您可以有效地检索给定的Alexa ID + Object的行,该行将被完全索引。

请参阅: 使用查询

您无法使用相同的主键创建多个条目。 请创建复合键(多个键一起作为主键)。 请注意,您不能拥有相同组合的多个记录

您可以使用排序键,例如,您可以将AlexaUserID作为主键,而不是Object作为排序键。

如果您想查询所有具有相同 AlexaUserID 的用户,您可以使用 DynamoDB 的查询API。 (这很重要,因为 get_item() 不会起作用,因为为此您必须同时提供主键和排序键)。

例如;

import boto3
from boto3.dynamodb.conditions import Key

client = boto3.resource('dynamodb')
table = client.Table('yourCoolTableName')

let userName = "thisIsMyAlexaUserName"

response = table.query(
     KeyConditionExpression=Key('AlexaUserID').eq(userName)
)    

items = response['Items']

您可以在此处阅读有关查询 API 的更多信息, 这里还有来自AWS 自己的文档的示例。

暂无
暂无

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

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