繁体   English   中英

DynamoDB 中的表设计

[英]Table design in DynamoDB

我是 NoSQL 数据库和无服务器的初学者。 我的应用程序有一个名为Trips的表。 表格的参数是{id, route, cost, selling, type, date, LR, asset }和一堆其他不相关的文档编号,其中id由uuid生成。

现在我想查询数据库给我

  1. 使用日期参数返回日期范围内的所有行程。
  2. 使用日期和资产参数返回给定时间段内资产的所有行程。
  3. 使用日期路线参数返回给定时间段内路线的所有行程。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM