如何在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 中实现这个吗?
- 如何存储关系数据?
- 在单个查询中检索包括关系数据在内的数据?
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,它要求您对如何构建和访问数据有不同的心态。它要求您提前考虑查询数据的方式。它当然不如关系数据库灵活,但它为您提供的是可伸缩性,前提是您的数据结构正确。
- 如何存储关系数据?
这是实现此目的的一种方法(单一 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”)。
- 用户地址在“数据”字段。随意拥有任意数量的字段。
- 在单个查询中检索包括关系数据在内的数据?
这是一个使用 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
我是 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 中实现这个吗?
- 如何存储关系数据?
- 在单个查询中检索包括关系数据在内的数据?
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,它要求您对如何构建和访问数据有不同的心态。它要求您提前考虑查询数据的方式。它当然不如关系数据库灵活,但它为您提供的是可伸缩性,前提是您的数据结构正确。
- 如何存储关系数据?
这是实现此目的的一种方法(单一 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”)。
- 用户地址在“数据”字段。随意拥有任意数量的字段。
- 在单个查询中检索包括关系数据在内的数据?
这是一个使用 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