[英]Table design in DynamoDB
我是 NoSQL 数据库和无服务器的初学者。 我的应用程序有一个名为Trips
的表。 表格的参数是{id, route, cost, selling, type, date, LR, asset }
和一堆其他不相关的文档编号,其中id由uuid生成。
现在我想查询数据库给我
2 和 3 使用 keyConditionExpression 工作正常但对于 1 我需要在扫描中使用 filterExpression 而不是查询,这可能会使它相对较慢,因为它是在查询完成后执行的。 有没有更好的方法来形成模式?
在Trips
表中,架构是这样的
tripTable:
Type: "AWS::DynamoDB::Table"
Properties:
AttributeDefinitions:
[
{ "AttributeName": "id", "AttributeType": "S" },
{ "AttributeName": "date", "AttributeType": "S" },
{ "AttributeName": "Asset", "AttributeType": "S" },
{ "AttributeName": "Route", "AttributeType": "S" },
]
KeySchema:
[
{ "AttributeName": "date", "KeyType": "HASH" },
{ "AttributeName": "id", "KeyType": "RANGE" },
]
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
StreamSpecification:
StreamViewType: "NEW_AND_OLD_IMAGES"
TableName: ${self:provider.environment.TRIPS}
GlobalSecondaryIndexes:
- IndexName: TripsVSAssets
KeySchema:
- AttributeName: asset
KeyType: HASH
- AttributeName: date
KeyType: RANGE
Projection:
ProjectionType: ALL
ProvisionedThroughput:
ReadCapacityUnits: "5"
WriteCapacityUnits: "5"
GlobalSecondaryIndexes:
- IndexName: RoutesVSAssets
KeySchema:
- AttributeName: route
KeyType: HASH
- AttributeName: date
KeyType: RANGE
Projection:
ProjectionType: ALL
ProvisionedThroughput:
ReadCapacityUnits: "5"
WriteCapacityUnits: "5"
我最近遇到了类似的问题,并选择使用year
作为分区键和日期作为排序键。 这适合我的数据量,让我可以按日期查询,而且大部分情况下只运行一个查询。 如果您有大量数据,也许month
甚至week
会更合适(或完全不同)。
通过我的方法,我只需要检查我想要查看的日期范围是否跨越两年,在那些情况下(即很少),Lambda 会进行两次查询并合并结果。 我在下面包含了一些代码草案,以防它有用(可能有更好的方法,但这对我有用:)我还推荐快速阅读: https:https://aws.amazon.com/blogs/database/choosing-右边的 dynamodb 分区键 / 。
module.exports.getLatest = async event => {
// some date and formatting code here not included
var params1 = {
ExpressionAttributeNames: { "#date": "date", "#year": "year" },
ExpressionAttributeValues: {
':d': isoDate,
':y1': y1
},
KeyConditionExpression: '#year = :y1 AND #date > :d',
TableName: process.env.HEADLINES_TABLE
}
if (y1 != y2) {
// define var params2 (the same as params1 except it uses y2)
}
try {
let result;
// if the date range cuts across partitions (years), fire off two queries and wait for both
if(y1 != y2) {
let resultPromise1 = client.query(params1).promise();
let resultPromise2 = client.query(params2).promise();
const [result1, result2] = await Promise.all([resultPromise1,resultPromise2]);
result = [...result1.Items, ...result2.Items];
} else {
result = await client.query(params1).promise();
}
return {
// stringify and return result.Items, statuscode 200 etc.
}
}
// catch {} code here (irrelevant for the answer)
}
您还需要一个索引列,其中分区键(哈希类型)将是一个随机数,比方说从 0 到 20。排序键(范围类型),再次将日期放在那里。
因此,要查询某个时间段内的所有行程,需要并行查询 20 次,partition Key 为 0 到 20 之间的每个数字,Sort Key 为时间范围。
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-modeling-nosql-B.html
检查上面的指南,go 到页面末尾的表格并检查第 5 个条目
如果您在此处进行扫描,则 dynamoDB 将向您收取每个分区键的费用。 在上述并行查询技术中,您只需为 N 次查询付费(在上述情况下为 20 次)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.