如何在dynamodb中实现一对多关系?

How to achieve one to many relation in dynamodb?

我是 dynamodb 的新手,但曾与 MongoDB 合作过。在阅读 dynamodb 一对多关系的 aws 文档时,我感到非常困惑。

所以我的情况是:

例如,我有表用户和地址:

Table: User
----
username
fname
lname
address: ref to addresses

Table: Addresses
----------
address line 1
address line 2
city
Zip
state
country

你能帮我看看如何在 dynamodb 中实现这个吗?

  1. 如何存储关系数据?
  2. 在单个查询中检索包括关系数据在内的数据?

DynamoDB 不是关系数据库。您无法执行您正在考虑的关系请求类型(特别是在您的问题 #2 中描述的单个查询中)。它需要以不同的方式思考您将如何存储和访问数据,因此它可能不是适合您的应用程序的技术。

Dynamo 不提供外键或 table 连接。每个 table 都有一个分区键 (PK),或者分区键和排序键 (SK) 的组合。当一个 table 只有一个 PK 时,它只能查询单个项目。当它既有PK又有SK时,可以PK/SK查询单个item,也可以查询PK相同的所有item

您描述的实现 1-to-N 数据的一种方法如下所示:

Table: Users
------------
[PK] userId
username
fname
lname

Table: Addresses
----------------
[PK] userId
[SK] addressId
address line 1
address line 2
city
zip
state
country

在此布局中,您仍然需要两次调用 Dynamo 才能获取用户的所有信息,包括地址。您将通过该用户 ID 对用户 table 进行单个 getItem 调用,并且您将通过同一用户 ID 对地址进行查询调用。第一次调用将 return 单个用户记录,第二次调用将 return 地址记录列表,按 addressId 排序。

您必须手动管理您的数据。由于没有外键,因此也没有约束或级联。如果您不小心,很容易得到孤立数据。同样,Dynamo 可能不是最适合您的应用程序的工具。

我在这里所描述的只是表面现象。对于任何希望使用 DynamoDB 构建企业软件进行数据存储的人来说,了解其架构方法和最佳实践至关重要。来自 SQL 甚至 MongoDB 背景,您的直觉可能会让您误入歧途,导致您构建性能不佳且难以调试的东西。对于合适的工作类型,它是一个极其强大的工具,但您必须尽职调查才能首先了解它。

--

编辑补充:我上面描述的方法甚至不是一个好方法! AWS 共享了文档并讨论了这类事情,包括他们的 Best Practices for DynamoDB,这远远超出了这个答案的范围。

使用 DynamoDB,它要求您对如何构建和访问数据有不同的心态。它要求您提前考虑查询数据的方式。它当然不如关系数据库灵活,但它为您提供的是可伸缩性,前提是您的数据结构正确。

  1. 如何存储关系数据?

这是实现此目的的一种方法(单一 table 设计)。

pk sk data
user111 address|mumbai|1 mumbai 1, india
user111 address|mumbai|2 mumbai 2, india
user111 address|delhi|1 delhi 1, india
user222 address|chennai|1 chennai 1, india
  • 使用用户 ID 作为分区键(“pk”)。
  • 使用用户地址作为排序键(“sk”)。
  • 用户地址在“数据”字段。随意拥有任意数量的字段。
  1. 在单个查询中检索包括关系数据在内的数据?

这是一个使用 AWS SDK 的示例 javascript。

const docClient = new AWS.DynamoDB.DocumentClient()

const params = {
  TableName: 'users',
  KeyConditionExpression: '#pk = :userId and begins_with(#sk, :data)',
  ExpressionAttributeNames: {
    "#pk": "pk",
    "#sk": "sk"
  },
  ExpressionAttributeValues: {
    ":userId": "user111",
    ":data": "address|"
  }
}

// get addresses
const res = await docClient.query(params).promise()

这里的想法是使用“begins_with”来检索用户地址。这就是您在 DynamoDB 中为一对多关系建模的方式。

更多信息: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-sort-keys.html