我正在为DynamoDB寻找最合适的表结构 将由存储库提交(git)提交的表。
系统中有两个同样受欢迎的请求:
unique(repository + sha)
[拒绝,如果不是唯一的] repository + sha
n
提交我尝试创建一个包含hash: repository, range: sha
KeySchema的表
以及hash: repository, range: createdAt, projection: ALL
这具有能够以原子方式拒绝提交的优点 如果它与另一个提交具有相同的存储库+ sha(通过ConditionExpression)。 它的缺点是需要2倍的尺寸(因为我需要能够投射) 第三个查询的所有键。)
有没有办法在没有2x尺寸要求的情况下支持上述三个查询。
这是代码,澄清:
async function createCommitsTable() {
await dyn.createTable({
ProvisionedThroughput,
TableName: COMMITS,
AttributeDefinitions: [
{AttributeName: 'repository', AttributeType: 'S'},
{AttributeName: 'sha', AttributeType: 'S'},
{AttributeName: 'createdAt', AttributeType: 'N'},
],
KeySchema: [
{AttributeName: 'repository', KeyType: 'HASH'},
{AttributeName: 'sha', KeyType: 'RANGE'},
],
LocalSecondaryIndexes: [{
IndexName: 'CreatedAtIndex',
Projection: {ProjectionType: 'ALL'},
KeySchema: [
{AttributeName: 'repository', KeyType: 'HASH'},
{AttributeName: 'createdAt', KeyType: 'RANGE'},
]
}]
})
}
将提交放入表中:
async function putCommits() {
await dc.put({
TableName: COMMITS,
Item: {
repository: 'linux',
sha: '6a13feb9c82803e2b815eca72fa7a9f5561d7861',
createdAt: Date.now()
},
ConditionExpression:
'attribute_not_exists(repository) and attribute_not_exists(sha)'
})
}
在表中查询单个和多个提交(按createdAt
排序):
async function queryCommits() {
console.log('[single commit]:\n', await dc.get({
TableName: COMMITS,
Key: {
repository: 'linux',
sha: '6a13feb9c82803e2b815eca72fa7a9f5561d7861'
}
}));
console.log('[commits by repo]:\n', await dc.query({
TableName: COMMITS,
IndexName: 'CreatedAtIndex',
KeyConditionExpression: 'repository = :repository',
ExpressionAttributeValues: {
':repository': 'linux'
}
}));
}
答案 0 :(得分:2)
尝试使用createdAt和sha的复合键,如下所示:
async function createCommitsTable() {
await dyn.createTable({
ProvisionedThroughput,
TableName: COMMITS,
AttributeDefinitions: [
{AttributeName: 'repository', AttributeType: 'S'},
{AttributeName: 'createdAt-sha', AttributeType: 'S'},
],
KeySchema: [
{AttributeName: 'repository', KeyType: 'HASH'},
{AttributeName: 'createdAt-sha', KeyType: 'RANGE'},
]
})
}
如果使用可排序的时间戳字符串,它允许您将createdAt-sha连接用作排序键,并在写入中使用contains作为条件,如下所示:
async function putCommits() {
await dc.put({
TableName: COMMITS,
Item: {
repository: 'linux',
createdAt-sha: Date.now() + '-6a13feb9c82803e2b815eca72fa7a9f5561d7861'
},
ConditionExpression:
'attribute_not_exists(repository) and NOT contains("createdAt-sha", sha)'
})
}
然后,您可以按日期查询表中的已排序提交。不确定所有这些格式是否正确,但这应该是一般的想法。