这个MySQL查询的等效DynamoDB解决方案是什么?

时间:2016-03-18 19:57:44

标签: amazon-dynamodb

我熟悉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需要不同的方法,那么在这种情况下什么是合适的解决方案呢?

1 个答案:

答案 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
}
相关问题