

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 Athena 访问、查询和联接 Amazon DynamoDB 表
<a name="access-query-and-join-amazon-dynamodb-tables-using-athena"></a>

*Moinul Al-Mamun，Amazon Web Services*

## Summary
<a name="access-query-and-join-amazon-dynamodb-tables-using-athena-summary"></a>

此模式说明如何使用 Amazon Athena DynamoDB 连接器在 Amazon Athena 和 Amazon DynamoDB 之间建立连接。连接器使用 AWS Lambda 函数查询 DynamoDB 中的数据。您无需编写任何代码即可设置连接。建立连接后，您可以[使用 Athena 联合查询](https://docs.aws.amazon.com/athena/latest/ug/connect-to-a-data-source.html)从 Athena 运行 SQL 命令，从而快速访问和分析 DynamoDB 表。您还可以将一个或多个 DynamoDB 表相互联接，或联接到其他数据来源，例如 Amazon Redshift 或 Amazon Aurora。

## 先决条件和限制
<a name="access-query-and-join-amazon-dynamodb-tables-using-athena-prereqs"></a>

**先决条件**
+ 一个活跃的 AWS 账户，拥有管理 DynamoDB 表、Athena 数据来源、Lambda 和 AWS Identity and Access Management（IAM）角色的权限
+ 一个 Amazon Simple Storage Service（Amazon S3）存储桶，Athena 可以在其中存储查询结果
+ 一个 S3 存储桶，Athena DynamoDB 连接器可以在其中保存数据
+ 支持 [Athena 引擎版本 2](https://docs.aws.amazon.com/athena/latest/ug/engine-versions-reference-0002.html) 的 AWS 区域
+ 访问 Athena 和所需 S3 存储桶的 IAM 权限
+ [Amazon Athena DynamoDB 连接器](https://github.com/awslabs/aws-athena-query-federation/tree/master/athena-dynamodb)，已安装

**限制**

查询 DynamoDB 表需要付费。表大小超过几千兆字节 (GBs) 可能会产生高昂的成本。我们建议您在执行任何全表 SCAN 操作之前考虑成本。有关更多信息，请参阅 [Amazon DynamoDB 定价](https://aws.amazon.com/dynamodb/pricing/)。为了降低成本并实现高性能，我们建议您始终在查询中使用 LIMIT（例如，`SELECT * FROM table1 LIMIT 10`）。此外，在生产环境中执行 JOIN 或 GROUP BY 查询之前，请考虑表的大小。如果您的表太大，请考虑其他选项，例如[将表迁移到 Amazon S3](https://aws.amazon.com/blogs/database/simplify-amazon-dynamodb-data-extraction-and-analysis-by-using-aws-glue-and-amazon-athena/)。

## 架构
<a name="access-query-and-join-amazon-dynamodb-tables-using-athena-architecture"></a>

下图显示了用户如何从 Athena 对 DynamoDB 表运行 SQL 查询。

![\[连接 Athena 和 DynamoDB 以运行 SQL 查询的工作流。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/e6ff94af-d208-40c7-94e4-af257755a603/images/bc8e0132-b578-463b-bf55-3c39ce359c17.png)


下图显示了如下工作流：

1. 要查询 DynamoDB 表，用户需要从 Athena 运行 SQL 查询。

1. Athena 启动 Lambda 函数。

1. Lambda 函数查询 DynamoDB 表中请求的数据。

1. DynamoDB 将请求的数据返回给 Lambda 函数。然后，该函数通过 Athena 将查询结果传输给用户。

1. Lambda 函数将数据存储在 S3 存储桶中。

**技术堆栈**
+ Amazon Athena
+ Amazon DynamoDB
+ Amazon S3
+ AWS Lambda

## 工具
<a name="access-query-and-join-amazon-dynamodb-tables-using-athena-tools"></a>
+ [Amazon Athena](https://docs.aws.amazon.com/athena/latest/ug/what-is.html) 是一种交互式查询服务，可帮助您使用标准 SQL 直接在 Amazon S3 中分析数据。
+ [Amazon Athena DynamoDB Connector](https://github.com/awslabs/aws-athena-query-federation/tree/master/athena-dynamodb) 是一种 AWS 工具，它使 Athena 能够与 DynamoDB 连接并使用 SQL 查询访问您的表。
+ [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) 是一项完全托管式 NoSQL 数据库服务，可提供快速、可预测、可扩展的性能。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 是一项计算服务，可帮助您运行代码，而无需预置或管理服务器。它仅在需要时运行您的代码，并且能自动扩缩，因此您只需为使用的计算时间付费。

## 操作说明
<a name="access-query-and-join-amazon-dynamodb-tables-using-athena-epics"></a>

### 创建示例 DynamoDB 表
<a name="create-sample-dynamodb-tables"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 创建第一个示例表。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-query-and-join-amazon-dynamodb-tables-using-athena.html) | 开发者版 | 
| 将示例数据插入到第一个表中。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-query-and-join-amazon-dynamodb-tables-using-athena.html)<pre>{<br />  "PK1": "1234",<br />  "SK1": "info",<br />  "Salary": "5000"<br /> }</pre><pre>{<br />  "PK1": "1235",<br />  "SK1": "info",<br />  "Salary": "5200"<br /> }</pre> | 开发者版 | 
| 创建第二个示例表。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-query-and-join-amazon-dynamodb-tables-using-athena.html) | 开发者版 | 
| 将示例数据插入到第二个表中。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-query-and-join-amazon-dynamodb-tables-using-athena.html)<pre>{<br />  "PK2": "1234",<br /> "SK2": "bonus",<br /> "Bonus": "500"<br />}</pre><pre>{<br />  "PK2": "1235",<br /> "SK2": "bonus",<br /> "Bonus": "1000"<br />}</pre> | 开发者版 | 

### 在 Athena 中为 DynamoDB 创建数据来源
<a name="create-a-data-source-in-athena-for-dynamodb"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 设置数据来源连接器。 | 为 DynamoDB 创建数据来源，然后创建 Lambda 函数以连接到该数据来源。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-query-and-join-amazon-dynamodb-tables-using-athena.html) | 开发者版 | 
| 验证 Lambda 函数是否可以访问 S3 溢出存储桶。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-query-and-join-amazon-dynamodb-tables-using-athena.html)如果遇到错误，请参阅此模式中的*其他信息*部分以获取指导。 | 开发者版 | 

### 从 Athena 访问 DynamoDB 表
<a name="access-dynamodb-tables-from-athena"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 查询 DynamoDB 表。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-query-and-join-amazon-dynamodb-tables-using-athena.html) | 开发者版 | 
| 连接两个 DynamoDB 表。 | DynamoDB 是 NoSQL 数据存储，不支持 SQL 联接操作。因此，您必须对两个 DynamoDB 表执行联接操作：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-query-and-join-amazon-dynamodb-tables-using-athena.html)<pre>SELECT pk1, salary, bonus FROM dydbtable1 t1<br /> JOIN dydbtable2 t2 ON t1.pk1 = t2.pk2;</pre> | 开发者版 | 

## 相关资源
<a name="access-query-and-join-amazon-dynamodb-tables-using-athena-resources"></a>
+ [Amazon Athena DynamoDB 连接器](https://github.com/awslabs/aws-athena-query-federation/tree/master/athena-dynamodb)（AWS Labs）
+ [使用 Amazon Athena 的新联合查询查询任何数据来源](https://aws.amazon.com/blogs/big-data/query-any-data-source-with-amazon-athenas-new-federated-query/)（AWS 大数据博客）
+ [Athena 引擎版本参考](https://docs.aws.amazon.com/athena/latest/ug/engine-versions-reference.html)（Athena 用户指南）
+ [使用 AWS Glue 和 Amazon Athena 简化 Amazon DynamoDB 数据提取和分析](https://aws.amazon.com/blogs/database/simplify-amazon-dynamodb-data-extraction-and-analysis-by-using-aws-glue-and-amazon-athena/)（AWS 数据库博客）

## 附加信息
<a name="access-query-and-join-amazon-dynamodb-tables-using-athena-additional"></a>

如果您在 Athena 中使用 `spill_bucket` 的 `{bucket_name}/folder_name/` 格式运行查询，则可能会收到以下错误消息：

```
"GENERIC_USER_ERROR: Encountered an exception[java.lang.RuntimeException] from your LambdaFunction[arn:aws:lambda:us-east-1:xxxxxx:function:testdynamodb] executed in context[retrieving meta-data] with message[You do NOT own the spill bucket with the name: s3://amzn-s3-demo-bucket/athena_dynamodb_spill_data/]
This query ran against the "default" database, unless qualified by the query. Please post the error message on our forum  or contact customer support with Query Id: [query-id]"
```

要解决此错误，请将 Lambda 函数的环境变量 `spill_bucket` 更新为 `{bucket_name_only}`，然后更新存储桶写入访问权限的以下 Lambda IAM policy：

```
{
             "Action": [
                 "s3:GetObject",
                 "s3:ListBucket",
                 "s3:GetBucketLocation",
                 "s3:GetObjectVersion",
                 "s3:PutObject",
                 "s3:PutObjectAcl",
                 "s3:GetLifecycleConfiguration",
                 "s3:PutLifecycleConfiguration",
                 "s3:DeleteObject"
            ],
             "Resource": [
                 "arn:aws:s3:::spill_bucket",
                 "arn:aws:s3:::spill_bucket/*"
            ],
             "Effect": "Allow"
        }
```

或者，您可以删除之前创建的 Athena 数据来源连接器，然后仅对 `spill_bucket` 使用 `{bucket_name}` 重新创建它。