我熟悉MySQL,并开始将Amazon DynamoDB用于新项目。
假设我有一个像这样的MySQL表:
CREATE TABLE foo (
id CHAR(64) NOT NULL,
scheduledDelivery DATETIME NOT NULL,
-- ...other columns...
PRIMARY KEY(id),
INDEX schedIndex (scheduledDelivery)
);
注意辅助索引schedIndex
,它应该加速以下查询(定期执行):
SELECT *
FROM foo
WHERE scheduledDelivery <= NOW()
ORDER BY scheduledDelivery ASC
LIMIT 100;
即:拿出将要交付的100件最旧的物品。
使用DynamoDB,我可以使用id
列作为主分区键。
但是,我不明白如何避免在DynamoDB中进行全表扫描。添加辅助索引时,我必须始终指定&#34; 分区键&#34;。但是,(用MySQL的话说)我看到了这些问题:
scheduledDelivery
列 不唯一,因此无法将其用作分区键本身AFAIK id
添加为唯一分区键并使用scheduledDelivery
作为&#34;排序键&#34;对我来说听起来像(id, scheduledDelivery)
二级索引,这使得该索引非常无用我知道MySQL和DynamoDB需要不同的方法,那么在这种情况下什么是合适的解决方案呢?
答案 0 :(得分:1)
使用这种查询无法避免全表扫描。
但,您可以将其伪装成Query
操作,这样您就可以对结果进行排序(Scan
无法实现)。
您必须先创建GSI。我们将其命名为scheduled_delivery-index
。
我们将索引的分区键指定为名为fixed_val
的属性,并将我们的排序键指定为scheduled_delivery
。
fixed_val
将包含您想要的任何值,但它必须始终是该值,您必须从客户端知道它。为了这个例子,我们假设fixed_val
始终是1
。
GSI密钥不必是唯一的,因此如果有两个重复的scheduled_delivery
值,请不要担心。
您可以像这样查询表格:
var now = Date.now();
//...
{
TableName: "foo",
IndexName: "scheduled_delivery-index",
ExpressionAttributeNames: {
"#f": "fixed_value",
"#d": "scheduled_delivery"
},
ExpressionAttributeValues: {
":f": 1,
":d": now
},
KeyConditionExpression: "#f = :f and #d <= :d",
ScanIndexForward: true
}