

# 使用 Athena ACID 事务
<a name="acid-transactions"></a>

术语“ACID 事务”是指确保数据库事务中数据完整性的一组属性（[原子性](https://en.wikipedia.org/wiki/Atomicity_(database_systems))、[一致性](https://en.wikipedia.org/wiki/Consistency_(database_systems))、[隔离性](https://en.wikipedia.org/wiki/Isolation_(database_systems))和[持久性](https://en.wikipedia.org/wiki/Durability_(database_systems))）。ACID 事务使多个用户能够以原子方式并发可靠地添加和删除 Amazon S3 对象，同时通过维持针对数据湖查询的读取一致性，来隔离任何现有查询。Athena ACID 事务在 Athena SQL 数据操作语言（DML）中添加了对插入、删除、更新和时间旅行操作的单表支持。您和多个并发用户可以使用 Athena ACID 事务对 Amazon S3 数据进行可靠的行级修改。Athena 事务会自动管理锁定语义和协调，无需使用自定义记录锁定解决方案。

Athena ACID 事务和熟悉的 SQL 语法简化了对业务和监管数据的更新。例如，要响应数据擦除请求，您可以执行 SQL `DELETE` 操作。要手动更正记录，您可以使用单个 `UPDATE` 语句。要恢复最近删除的数据，您可以使用 `SELECT` 语句发出时间旅行查询。

由于它们都基于共享表格格式构建，因此 Athena ACID 事务与其它同样支持共享表格格式的服务和引擎兼容，例如 [Amazon EMR](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-what-is-emr.html) 和 [Apache Spark](https://spark.apache.org/)。

可以通过 Athena 控制台、API 操作以及 ODBC 和 JDBC 驱动程序访问 Athena 事务。

**Topics**
+ [查询 Linux Foundation Delta Lake 表](delta-lake-tables.md)
+ [查询 Apache Hudi 数据集](querying-hudi.md)
+ [查询 Apache Iceberg 表](querying-iceberg.md)

# 查询 Linux Foundation Delta Lake 表
<a name="delta-lake-tables"></a>

Linux Foundation [Delta Lake](https://delta.io/) 是一种用于大数据分析的表格格式。您可以使用 Amazon Athena 直接读取存储在 Amazon S3 中的 Delta Lake 表，无需生成清单文件或运行 `MSCK REPAIR` 语句。

Delta Lake 格式会存储每个数据文件每列的最小值和最大值。Athena 实施利用该信息在谓词上启用文件跳过，以消除不需要的文件。

## 注意事项和限制
<a name="delta-lake-tables-considerations-and-limitations"></a>

Athena 中的 Delta Lake 支持具有以下注意事项和限制：
+ **仅包含 AWS Glue 目录的表** – 仅通过注册到 AWS Glue 的表支持原生 Delta Lake。如果 Delta Lake 表已注册到其他元存储，您仍可保留该表并将其视为主元存储。由于 Delta Lake 元数据存储在文件系统（例如 Amazon S3）中而不是元存储中，因此 Athena 只需 AWS Glue 中的位置属性即可从 Delta Lake 表中进行读取。
+ **V3 engine only**（仅限 V3 引擎）– 仅支持在 Athena 引擎版本 3 上进行 Delta Lake 查询。您必须确保创建的工作组配置为使用 Athena 引擎版本 3。
+ **No time travel support**（不支持时间旅行）– 不支持使用 Delta Lake 时间旅行功能的查询。
+ **Read only**（只读）– 不支持编写 `UPDATE`、`INSERT`、或 `DELETE` 等 DML 语句。
+ **Lake Formation 支持** – Lake Formation 集成可用于架构与 AWS Glue 同步的 Delta Lake 表。有关更多信息，请参阅《*AWS Lake Formation 开发人员指南*》中的 [AWS Lake Formation 与 Amazon Athena 一起使用](https://docs.aws.amazon.com/lake-formation/latest/dg/athena-lf.html)和[为 Delta Lake 表设置权限](https://docs.aws.amazon.com/lake-formation/latest/dg/set-up-delta-table.html)。
+ **Limited DDL support**（有限的 DDL 支持）– 支持以下 DDL 语句：`CREATE EXTERNAL TABLE`、`SHOW COLUMNS`、`SHOW TBLPROPERTIES`、`SHOW PARTITIONS`、`SHOW CREATE TABLE` 和 `DESCRIBE`。有关使用 `CREATE EXTERNAL TABLE` 语句的信息，请参阅 [Delta Lake 表入门](delta-lake-tables-getting-started.md) 一节。
+ **不支持跳过 Amazon Glacier 对象** – 如果 Linux Foundation Delta Lake 表中的对象属于 Amazon Glacier 存储类别，将 `read_restored_glacier_objects` 表属性设置为 `false` 则无效。

  例如，假设发出以下命令：

  ```
  ALTER TABLE table_name SET TBLPROPERTIES ('read_restored_glacier_objects' = 'false')
  ```

  对于 Iceberg 和 Delta Lake 表，该命令会生成错误 Unsupported table property key: read\$1restored\$1glacier\$1objects。对于 Hudi 表，`ALTER TABLE` 命令不会产生错误，但是仍无法跳过 Amazon Glacier 对象。在 `ALTER TABLE` 命令之后运行 `SELECT` 查询会继续返回所有对象。
+ **加密表** – Athena 不支持原生读取 CSE-KMS 加密的 Delta Lake 表。这包括 SELECT 语句和 DDL 语句。

### Delta Lake 版本控制和 Athena
<a name="delta-lake-tables-versioning"></a>

Athena 不使用 Delta Lake 文档中列出的[版本控制](https://docs.delta.io/latest/releases.html)。要确定您的 Delta Lake 表是否与 Athena 兼容，请考虑以下两个特征：
+ **读取器版本**：每张 Delta Lake 表都提供读取器版本。目前，该版本为 1 到 3 的数字。如果查询包含 Athena 不支持的读取器版本的表，则查询将失败。
+ **表功能**：每个 Delta Lake 表也可以声明一组读取器/写入器功能。由于 Athena 对 Delta Lake 为只读支持，因此表写入器功能的兼容性不适用。但是，对于包含不支持的表读取器功能的表，对其的查询将失败。

下表显示了 Athena 支持的 Delta Lake 读取器版本和 Delta Lake 桌面读取器功能。


****  

| 查询类型 | 支持的读取器版本 | 支持的读取器功能 | 
| --- | --- | --- | 
| DQL（SELECT 语句） | <= 3 | [列映射](https://docs.delta.io/latest/delta-column-mapping.html)、[timestampnTZ](https://github.com/delta-io/delta/blob/master/PROTOCOL.md#timestamp-without-timezone-timestampntz) 和[删除向量](https://docs.delta.io/latest/delta-deletion-vectors.html) | 
| DDL | <= 1 | 不适用。只能在读取器版本为 2 或更高版本的表上声明读取器功能。 | 
+ 有关 Delta Lake 表功能的列表，请参阅 GitHub.com 上[表功能中的有效功能名称](https://github.com/delta-io/delta/blob/master/PROTOCOL.md#valid-feature-names-in-table-features)
+ 有关按协议版本划分的 Delta Lake 功能列表，请参阅 GitHub.com 上的 [Features by protocol version](https://docs.delta.io/latest/versioning.html#features-by-protocol-version)。

要在 Athena 中创建读取器版本高于 1 的 Delta Lake 表，请参阅[同步 Delta Lake 元数据](delta-lake-tables-syncing-metadata.md)。

**Topics**
+ [注意事项和限制](#delta-lake-tables-considerations-and-limitations)
+ [支持的列数据类型](delta-lake-tables-supported-data-types-columns.md)
+ [Delta Lake 表入门](delta-lake-tables-getting-started.md)
+ [使用 SQL 查询 Delta Lake 表](delta-lake-tables-querying.md)
+ [同步 Delta Lake 元数据](delta-lake-tables-syncing-metadata.md)
+ [其他资源](delta-lake-tables-additional-resources.md)

# 支持的列数据类型
<a name="delta-lake-tables-supported-data-types-columns"></a>

本部分介绍非分区列和分区列支持的数据类型。

## 支持的非分区列数据类型
<a name="delta-lake-tables-supported-data-types-non-partition-columns"></a>

对于非分区列，除 `CHAR` 外，支持 Athena 支持的所有数据类型（Delta Lake 协议本身不支持 `CHAR`）。支持的数据类型包括：

```
boolean
tinyint
smallint
integer
bigint
double
float
decimal
varchar
string
binary
date
timestamp
array
map
struct
```

## 支持的分区列数据类型
<a name="delta-lake-tables-supported-data-types-partition-columns"></a>

对于分区列，Athena 支持具有以下数据类型的表：

```
boolean
integer
smallint
tinyint
bigint
decimal
float
double
date
timestamp
varchar
```

有关 Athena 中数据类型的更多信息，请参阅 [Amazon Athena 中的数据类型](data-types.md)。

# Delta Lake 表入门
<a name="delta-lake-tables-getting-started"></a>

要进行查询，Delta Lake 表必须存在于 AWS Glue 中。如果表位于 Amazon S3 但不在 AWS Glue 中，请使用以下语法运行 `CREATE EXTERNAL TABLE` 语句。如果表已存在于 AWS Glue 中（例如，因为您正在将 Apache Spark 或其他引擎与 AWS Glue 结合使用），则可以跳过此步骤。请注意，列定义、SerDe 库和其他表属性会省略。与传统的 Hive 表不同，Delta Lake 表元数据是从 Delta Lake 事务日志中推断出来的，并直接同步到 AWS Glue。

```
CREATE EXTERNAL TABLE
  [db_name.]table_name
  LOCATION 's3://amzn-s3-demo-bucket/your-folder/'
  TBLPROPERTIES ('table_type' = 'DELTA')
```

**注意**  
此语句与启用了申请方付款功能的 S3 存储桶不兼容。如果要针对启用了申请方付款功能的 S3 存储桶创建 Delta Lake 表，请按照[同步 Delta Lake 元数据](delta-lake-tables-syncing-metadata.md)中的说明和 DDL 语句进行操作。
对于 Delta Lake 表，不允许包含除 `LOCATION` 和 `table_type` 属性外的 `CREATE TABLE` 语句。

# 使用 SQL 查询 Delta Lake 表
<a name="delta-lake-tables-querying"></a>

要查询 Delta Lake 表，请使用标准 SQL `SELECT` 语法：

```
[ WITH with_query [, ...] ]SELECT [ ALL | DISTINCT ] select_expression [, ...]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY [ ALL | DISTINCT ] grouping_element [, ...] ]
[ HAVING condition ]
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
[ ORDER BY expression [ ASC | DESC ] [ NULLS FIRST | NULLS LAST] [, ...] ]
[ OFFSET count [ ROW | ROWS ] ]
[ LIMIT [ count | ALL ] ]
```

有关 `SELECT` 语句的更多信息，请参阅 Athena 文档中的 [SELECT](select.md)。

Delta Lake 格式会存储每个数据文件每列的最小值和最大值。Athena 利用该信息在谓词上启用文件跳过，以消除不需要的文件。

# 同步 Delta Lake 元数据
<a name="delta-lake-tables-syncing-metadata"></a>

如果您使用 Athena 创建 Delta Lake 表，Athena 会将表元数据（包括架构、分区列和表属性）同步到 AWS Glue。随着时间推移，该元数据可能会中断与事务日志中基础表元数据的同步。要让表保持最新状态，您可以选择以下选项之一：
+ 为 Delta Lake 表使用 AWS Glue 爬网程序。有关更多信息，请参阅 *AWS 大数据博客*中的[带 AWS Glue 爬网程序的原生 Delta Lake 表支持的简介](https://aws.amazon.com/blogs/big-data/introducing-native-delta-lake-table-support-with-aws-glue-crawlers/)和《AWS Glue 开发人员指南》中的[计划 AWS Glue 爬网程序](https://docs.aws.amazon.com/glue/latest/dg/schedule-crawler.html)。
+ 在 Athena 中删除并重新创建表格。
+ 使用 SDK、CLI 或 AWS Glue 控制台手动更新 AWS Glue 中的架构。

请注意：以下功能要求您的 AWS Glue 架构始终具有与事务日志相同的架构：
+ Lake Formation
+ 视图
+ 行和列筛选器

如果您的工作流程不需要任何此功能，并且您不希望保持这种兼容性，则可以在 Athena 中使用 `CREATE TABLE` DDL，然后将 Amazon S3 路径作为 SerDe 参数添加到 AWS Glue 中。

## 使用 Athena 和 AWS Glue 控制台创建 Delta Lake 表
<a name="delta-lake-tables-syncing-metadata-console"></a>

您可以参考以下过程，使用 Athena 和 AWS Glue 控制台创建 Delta Lake 表。

**使用 Athena 和 AWS Glue 控制台创建 Delta Lake 表**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 在 Athena 查询编辑器中，使用以下 DDL 创建您的 Delta Lake 表。请注意：使用此方法时，`TBLPROPERTIES` 的值必须为 `'spark.sql.sources.provider' = 'delta'`，而不是 `'table_type' = 'delta'`。

   请注意：当您使用 Apache Spark（Athena for Apache Spark）或大多数其他引擎创建表时，会插入相同的架构（其中包含一个名为 `col` 的 `array<string>` 类型列）。

   ```
   CREATE EXTERNAL TABLE
      [db_name.]table_name(col array<string>)
      LOCATION 's3://amzn-s3-demo-bucket/your-folder/'
      TBLPROPERTIES ('spark.sql.sources.provider' = 'delta')
   ```

1. 通过 [https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/) 打开 AWS Glue 控制台。

1. 在导航窗格中，选择**数据目录**、**表**。

1. 在表的列表中，选择表的链接。

1. 在表格页面上，选择**操作**、**编辑表格**。

1. 在 **Serde 参数**部分，添加带有值 **s3://amzn-s3-demo-bucket/*your-folder*/** 的键 **path**。

1. 选择**保存**。

## 使用 AWS CLI 创建 Delta Lake 表
<a name="delta-lake-tables-syncing-metadata-cli"></a>

要使用 AWS CLI 创建 Delta Lake 表，请输入如下命令。

```
aws glue create-table --database-name dbname \
    --table-input '{"Name" : "tablename", "StorageDescriptor":{
            "Columns" : [
                {
                    "Name": "col",
                    "Type": "array<string>"
                }
            ],
            "Location" : "s3://amzn-s3-demo-bucket/<prefix>/",
            "SerdeInfo" : {
                "Parameters" : {
                    "serialization.format" : "1",
                    "path" : "s3://amzn-s3-demo-bucket/<prefix>/"
                }
            }
        },
        "PartitionKeys": [],
        "TableType": "EXTERNAL_TABLE",
        "Parameters": {
            "EXTERNAL": "TRUE",
            "spark.sql.sources.provider": "delta"
        }
    }'
```

# 其他资源
<a name="delta-lake-tables-additional-resources"></a>

有关将 Delta Lake 表与 AWS Glue 一起使用以及使用 Athena 查询表的讨论，请参阅 *AWS 大数据博客*中的[使用开源 Delta Lake 和 AWS Glue 处理 UPSERT 数据操作](https://aws.amazon.com/blogs/big-data/handle-upsert-data-operations-using-open-source-delta-lake-and-aws-glue/)。

# 查询 Apache Hudi 数据集
<a name="querying-hudi"></a>

[https://hudi.incubator.apache.org/](https://hudi.incubator.apache.org/)是一个开源数据管理框架，可简化增量递增数据的处理。记录级别的插入、更新、加入和删除操作的处理更加精细，从而降低了开销。`Upsert` 指的是将记录插入到现有数据集中（如果它们不存在）或对数据集进行更新（如果它们存在）的功能。

Hudi 处理数据插入和更新事件，而不会创建许多可能导致分析性能问题的小文件。Apache Hudi 会自动跟踪更改并合并文件，以便它们保持最佳大小。这样就不需要构建自定义解决方案来监控许多小文件并将其重写为大文件以减少其数量。

Hudi 数据集适用于以下使用案例：
+ 遵守隐私法规，如[《一般数据保护条例》](https://en.wikipedia.org/wiki/General_Data_Protection_Regulation)（GDPR）和[《加州消费者隐私法》](https://en.wikipedia.org/wiki/California_Consumer_Privacy_Act)（CCPA），这些法规将强制执行人们删除个人信息的权力或更改其数据使用方式。
+ 处理来自传感器和其它需要特定数据插入和更新事件的物联网 (IoT) 设备的流数据。
+ 实施[更改数据捕获 (CDC) 系统](https://en.wikipedia.org/wiki/Change_data_capture)。

Hudi 数据集可以采用以下类型之一：
+ **写入时复制 (CoW)** – 数据以列状格式存储 (Parquet)，并且每次更新都会在写入过程中创建一个新版本的文件。
+ **读取时合并 (MOR)** – 数据使用列式 (Parquet) 和基于行 (Avro) 的格式的组合进行存储。更新记录到基于行的 `delta` 文件中，并根据需要进行压缩以创建新版本的列式文件。

对于 CoW 数据集，每次更新记录时，包含该记录的文件都会使用更新后的值进行重写。对于 MoR 数据集，每次进行更新时，Hudi 仅写入已更改记录对应的行。MoR 更适合写入或更改繁重而读取量较少的工作负载。CoW 更适合更改频率较低但读取量繁重的工作负载。

Hudi 提供三个查询类型用于访问数据：
+ **快照查询** – 该查询用于查看截至给定提交或压缩操作时表的最新快照。对于 MOR 表，快照查询通过在查询时合并最新文件切片的基本文件和增量文件来显示表的最新状态。
+ **增量查询** – 查询只能看到自给定提交/压缩以来，写入表的新数据。这有效地提供了更改流以启用增量数据管道。
+ **读取优化查询** – 对于 MOR 表，查询将看到最新压缩的数据。对于 CoW 表，查询将看到最新提交的数据。

下表显示了适用于每种表类型的可用 Hudi 查询类型。


| 表类型 | 可用的 Hudi 查询类型 | 
| --- | --- | 
| 写入时复制 | 快照、增量 | 
| 读取时合并 | 快照、增量、读取优化 | 

有关在表和查询类型之间权衡的更多信息，请参阅 Apache Hudi 文档中的[表和查询类型](https://hudi.apache.org/docs/table_types/)。

## Hudi 术语变更：视图现在为查询
<a name="querying-hudi-hudi-dataset-table-types-terminology"></a>

从 Apache Hudi 发布版本 0.5.1 开始，以前所谓的视图现在称为查询。下表总结了旧新术语之间的变更。


| 旧术语 | 新术语 | 
| --- | --- | 
|  CoW：读取优化视图 MoR：实时视图  |  快照查询  | 
| 增量视图 | 增量查询 | 
| MoR 读取优化视图 | 读取优化的查询 | 

**Topics**
+ [Hudi 术语变更：视图现在为查询](#querying-hudi-hudi-dataset-table-types-terminology)
+ [注意事项和限制](querying-hudi-in-athena-considerations-and-limitations.md)
+ [写入时复制（CoW）创建表示例](querying-hudi-copy-on-write-create-table-examples.md)
+ [读取时合并（MoR）创建表示例](querying-hudi-merge-on-read-create-table-examples.md)
+ [使用 Hudi 元数据提高性能](querying-hudi-metadata-table.md)
+ [其他资源](querying-hudi-additional-resources.md)

# 注意事项和限制
<a name="querying-hudi-in-athena-considerations-and-limitations"></a>

使用 Athena 读取 Apache Hudi 表时，请考虑以下几点。
+ **读取和写入操作**：Athena 可以读取压缩的 Hudi 数据集，但不能写入 Hudi 数据。
+ **Hudi 版本**：Athena 支持 Hudi 版本 0.14.0（默认值）和 0.15.0。Athena 不保证与使用更高版本的 Hudi 创建的表具有读取兼容性。有关 Hudi 功能和版本控制的更多信息，请参阅 Apache 网站上的 [Hudi 文档](https://hudi.apache.org/)。请注意，Athena 上的 0.15.0 版 Hudi 连接器不支持引导启动表。要使用 Hudi 连接器 0.15.0，请设置以下表属性：

  ```
  ALTER TABLE table_name SET TBLPROPERTIES ('athena_enable_native_hudi_connector_implementation' = 'true')
  ```
+ **跨账户查询**：Hudi 连接器 0.15.0 版不支持跨账户查询。
+ **查询类型**：目前，Athena 支持快照查询和读取优化查询，但不支持增量查询。在 MOR 表上，所有在读取优化查询中显示的 数据均已压缩。这提供了良好的性能，但不包括最新的增量提交。快照查询包含最新的数据，但会但产生一些计算开销，这使得这些查询的性能降低。有关在表和查询类型之间权衡的更多信息，请参阅 Apache Hudi 文档中的[表和查询类型](https://hudi.apache.org/docs/table_types/)。
+ **增量查询** – Athena 不支持增量查询。
+ **CTAS** – Athena 不支持对 Hudi 数据执行 [CTAS](ctas.md) 或者 [INSERT INTO](insert-into.md)。如果您希望 Athena 支持编写 Hudi 数据集，请将反馈发送至 athena-feedback@amazon.com。

  有关编写 Hudi 数据的更多信息，请参阅以下资源：
  + 《[Amazon EMR 版本指南](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/)》中的[使用 Hudi 数据集](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-hudi-work-with-dataset.html)。
  + Apache Hudi 文档中的[写入数据](https://hudi.apache.org/docs/0.8.0/writing_data.html)。
+ **MSCK REPAIR TABLE** – 不支持在 Athena 的 Hudi 表上使用 MSCK REPAIR TABLE。如果您需要加载未在 AWS Glue 中创建的 Hudi 表，请使用 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md)。
+ **不支持跳过 Amazon Glacier 对象** – 如果 Apache Hudi 表中的对象属于 Amazon Glacier 存储类别，将 `read_restored_glacier_objects` 表属性设置为 `false` 则无效。

  例如，假设发出以下命令：

  ```
  ALTER TABLE table_name SET TBLPROPERTIES ('read_restored_glacier_objects' = 'false')
  ```

  对于 Iceberg 和 Delta Lake 表，该命令会生成错误 Unsupported table property key: read\$1restored\$1glacier\$1objects。对于 Hudi 表，`ALTER TABLE` 命令不会产生错误，但是仍无法跳过 Amazon Glacier 对象。在 `ALTER TABLE` 命令之后运行 `SELECT` 查询会继续返回所有对象。
+ **时间戳查询** – 当前，试图读取 Hudi 实时表中时间戳列的查询要么失败，要么产生空结果。此限制仅适用于读取时间戳列的查询。仅包含同一表中非时间戳列的查询会成功。

  失败的查询会返回类似于以下内容的消息：

  GENERIC\$1INTERNAL\$1ERROR: class org.apache.hadoop.io.ArrayWritable cannot be cast to class org.apache.hadoop.hive.serde2.io.TimestampWritableV2 (org.apache.hadoop.io.ArrayWritable and org.apache.hadoop.hive.serde2.io.TimestampWritableV2 are in unnamed module of loader io.trino.server.PluginClassLoader @75c67992)
+ **0.15.0 Hudi 连接器上的 Lake Formation 权限**：只有当您通过将表属性 `athena_enable_native_hudi_connector_implementation` 设置为 `true` 来选择使用原生 Hudi 连接器（版本 0.15.0）时，此限制才适用。默认情况下，Athena 使用 Hudi 连接器版本 0.14.0，其不需要此额外权限。要查询受 Lake Formation 保护的表，您必须授予 Lake Formation 对表的数据位置和 `.hoodie` 元数据目录的权限。例如，如果您的 Hudi 表位于 `s3://bucket/hudi-table/`，则必须在 Lake Formation 中注册并授予对 `s3://bucket/hudi-table/` 和 `s3://bucket/hudi-table/.hoodie/` 的权限。`.hoodie` 目录包含 Athena 在查询规划期间需要读取的元数据文件（例如 `hoodie.properties`）。如果没有访问 `.hoodie` 目录的权限，则查询将失败并出现权限被拒绝错误。

# 写入时复制（CoW）创建表示例
<a name="querying-hudi-copy-on-write-create-table-examples"></a>

如果您有已在 AWS Glue 中创建的 Hudi 表，您可以直接在 Athena 中查询它们。当您在 Athena 中创建分区 Hudi 表时，您必须运行 `ALTER TABLE ADD PARTITION` 以加载 Hudi 数据，然后再查询这些数据。

## 未分区 CoW 表
<a name="querying-hudi-nonpartitioned-cow-table"></a>

以下示例在 Athena 中创建了一个未分区的 CoW 表。

```
CREATE EXTERNAL TABLE `non_partition_cow`(
  `_hoodie_commit_time` string,
  `_hoodie_commit_seqno` string,
  `_hoodie_record_key` string,
  `_hoodie_partition_path` string,
  `_hoodie_file_name` string,
  `event_id` string,
  `event_time` string,
  `event_name` string,
  `event_guests` int,
  `event_type` string)
ROW FORMAT SERDE
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
  'org.apache.hudi.hadoop.HoodieParquetInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
  's3://amzn-s3-demo-bucket/folder/non_partition_cow/'
```

## 分区 CoW 表
<a name="querying-hudi-partitioned-cow-table"></a>

以下示例在 Athena 中创建了一个已分区的 CoW 表。

```
CREATE EXTERNAL TABLE `partition_cow`(
  `_hoodie_commit_time` string, 
  `_hoodie_commit_seqno` string, 
  `_hoodie_record_key` string, 
  `_hoodie_partition_path` string, 
  `_hoodie_file_name` string, 
  `event_id` string, 
  `event_time` string, 
  `event_name` string, 
  `event_guests` int)
PARTITIONED BY ( 
  `event_type` string)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hudi.hadoop.HoodieParquetInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' 
LOCATION
  's3://amzn-s3-demo-bucket/folder/partition_cow/'
```

以下 `ALTER TABLE ADD PARTITION` 示例将两个分区添加到了示例 `partition_cow` 表。

```
ALTER TABLE partition_cow ADD
  PARTITION (event_type = 'one') LOCATION 's3://amzn-s3-demo-bucket/folder/partition_cow/one/' 
  PARTITION (event_type = 'two') LOCATION 's3://amzn-s3-demo-bucket/folder/partition_cow/two/'
```

# 读取时合并（MoR）创建表示例
<a name="querying-hudi-merge-on-read-create-table-examples"></a>

Hudi 在元存储中为 MoR 创建了两个表：一个用于快照查询的表，一个用于读取优化查询的表。两个表都可查询。在 0.5.1 之前的 Hudi 版本中，用于读优化查询的表具有您在创建表时指定的名称。从 Hudi 版本 0.5.1 开始，表名将默认以 `_ro` 为后缀。用于快照查询的表的名称是指定的名称，其中附加了 `_rt`。

## 未分区的读取时合并（MoR）表
<a name="querying-hudi-nonpartitioned-merge-on-read-table"></a>

以下示例在 Athena 中创建了一个未分区的 MoR 表用于读取优化查询。请注意，读取优化查询使用输入格式 `HoodieParquetInputFormat`。

```
CREATE EXTERNAL TABLE `nonpartition_mor`(
  `_hoodie_commit_time` string, 
  `_hoodie_commit_seqno` string, 
  `_hoodie_record_key` string, 
  `_hoodie_partition_path` string, 
  `_hoodie_file_name` string, 
  `event_id` string, 
  `event_time` string, 
  `event_name` string, 
  `event_guests` int, 
  `event_type` string)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hudi.hadoop.HoodieParquetInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' 
LOCATION
  's3://amzn-s3-demo-bucket/folder/nonpartition_mor/'
```

以下示例在 Athena 中创建了一个未分区的 MoR 表用于快照查询。对于快照查询，请使用输入格式 `HoodieParquetRealtimeInputFormat`。

```
CREATE EXTERNAL TABLE `nonpartition_mor_rt`(
  `_hoodie_commit_time` string, 
  `_hoodie_commit_seqno` string, 
  `_hoodie_record_key` string, 
  `_hoodie_partition_path` string, 
  `_hoodie_file_name` string, 
  `event_id` string, 
  `event_time` string, 
  `event_name` string, 
  `event_guests` int, 
  `event_type` string)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hudi.hadoop.realtime.HoodieParquetRealtimeInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' 
LOCATION
  's3://amzn-s3-demo-bucket/folder/nonpartition_mor/'
```

## 已分区的读取时合并（MoR）表
<a name="querying-hudi-partitioned-merge-on-read-table"></a>

以下示例在 Athena 中创建了一个已分区的 MoR 表用于读取优化查询。

```
CREATE EXTERNAL TABLE `partition_mor`(
  `_hoodie_commit_time` string, 
  `_hoodie_commit_seqno` string, 
  `_hoodie_record_key` string, 
  `_hoodie_partition_path` string, 
  `_hoodie_file_name` string, 
  `event_id` string, 
  `event_time` string, 
  `event_name` string, 
  `event_guests` int)
PARTITIONED BY ( 
  `event_type` string)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hudi.hadoop.HoodieParquetInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
  's3://amzn-s3-demo-bucket/folder/partition_mor/'
```

以下 `ALTER TABLE ADD PARTITION` 示例将两个分区添加到了示例 `partition_mor` 表。

```
ALTER TABLE partition_mor ADD
  PARTITION (event_type = 'one') LOCATION 's3://amzn-s3-demo-bucket/folder/partition_mor/one/'
  PARTITION (event_type = 'two') LOCATION 's3://amzn-s3-demo-bucket/folder/partition_mor/two/'
```

以下示例在 Athena 中创建了一个已分区的 MoR 表用于快照查询。

```
CREATE EXTERNAL TABLE `partition_mor_rt`(
  `_hoodie_commit_time` string, 
  `_hoodie_commit_seqno` string, 
  `_hoodie_record_key` string, 
  `_hoodie_partition_path` string, 
  `_hoodie_file_name` string, 
  `event_id` string, 
  `event_time` string, 
  `event_name` string, 
  `event_guests` int)
PARTITIONED BY ( 
  `event_type` string)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT 
  'org.apache.hudi.hadoop.realtime.HoodieParquetRealtimeInputFormat'
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
  's3://amzn-s3-demo-bucket/folder/partition_mor/'
```

同样，以下 `ALTER TABLE ADD PARTITION` 示例将两个分区添加到了示例 `partition_mor_rt` 表。

```
ALTER TABLE partition_mor_rt ADD
  PARTITION (event_type = 'one') LOCATION 's3://amzn-s3-demo-bucket/folder/partition_mor/one/'
  PARTITION (event_type = 'two') LOCATION 's3://amzn-s3-demo-bucket/folder/partition_mor/two/'
```

# 使用 Hudi 元数据提高性能
<a name="querying-hudi-metadata-table"></a>

Apache Hudi 有一个[元数据表](https://hudi.apache.org/docs/next/metadata/)，其中包含用于提高性能的索引功能，例如文件列表、使用列统计数据跳过数据以及基于布隆筛选器的索引。

在这些功能中，Athena 目前仅支持文件列表索引。文件列表索引通过从维护分区到文件映射的索引中获取信息，从而消除了“列表文件”之类的文件系统调用。这样就无需以递归方式列出表路径下的每个分区即可查看文件系统。当您处理大型数据集时，这种索引可以大大减少写入和查询期间获取文件列表时出现的延迟。还可以避免诸如 Amazon S3 `LIST` 调用的请求限制节流之类的瓶颈。

**注意**  
Athena 目前不支持数据跳过或布隆筛选器索引。

## 启用 Hudi 元数据表
<a name="querying-hudi-metadata-table-enabling-the-hudi-metadata-table"></a>

默认情况下，禁用基于元数据表的文件列表。要启用 Hudi 元数据表和相关的文件列表功能，请将 `hudi.metadata-listing-enabled` 表格属性设置为 `TRUE`。

**示例**  
以下 `ALTER TABLE SET TBLPROPERTIES` 示例在示例 `partition_cow` 表上启用元数据表。

```
ALTER TABLE partition_cow SET TBLPROPERTIES('hudi.metadata-listing-enabled'='TRUE')
```

## 使用引导程序生成的元数据
<a name="querying-hudi-hudi-dataset-table-types-bootstrap"></a>

从 Apache Hudi 版本 0.6.0 开始，引导启动操作功能可为现有的 Parquet 数据集提供更好的性能。引导操作只能生成元数据，使数据集保持原位，而不是重写数据集。

您可以使用 Athena 从引导启动操作中查询表，就像基于 Amazon S3 中数据的其他表一样。在您的 `CREATE TABLE` 语句中，在 `LOCATION` 子句指定 Hudi 表路径。

有关在 Amazon EMR 中使用引导启动操作创建 Hudi 表的更多信息，请参阅 AWS 大数据博客文章：[New features from Apache Hudi available in Amazon EMR](https://aws.amazon.com/blogs/big-data/new-features-from-apache-hudi-available-in-amazon-emr/)（在 Amazon EMR 中可用的 Apache Hudi 新功能）。

# 其他资源
<a name="querying-hudi-additional-resources"></a>

有关将 Apache Hudi 与 Athena 一起使用的其他资源，请参阅以下资源。

## 视频
<a name="querying-hudi-videos"></a>

以下视频展示了如何使用 Amazon Athena 查询基于 Amazon S3 的数据湖中的读取优化 Apache Hudi 数据集。

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/TVcreqxBaGA/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/TVcreqxBaGA)


## 博客文章
<a name="querying-hudi-big-data-blogs"></a>

以下 AWS 大数据博客文章包括关于如何将 Apache Hudi 与 Athena 一起使用的描述。
+ [使用 AWS Data Exchange 无缝共享 Apache Hudi 数据集](https://aws.amazon.com/blogs/big-data/use-aws-data-exchange-to-seamlessly-share-apache-hudi-datasets/) 
+ [通过 AWS DMS、Amazon Kinesis、AWS Glue 流式处理 ETL 和使用 Quick 的数据可视化创建基于 Apache HUDI 的近实时事务处理数据湖](https://aws.amazon.com/blogs/big-data/create-an-apache-hudi-based-near-real-time-transactional-data-lake-using-aws-dms-amazon-kinesis-aws-glue-streaming-etl-and-data-visualization-using-amazon-quicksight/) 
+ 要了解如何使用 AWS Glue 自定义连接器和 AWS Glue 2.0 作业来创建可以使用 Athena 查询的 Apache Hudi 表，请参阅 [Writing to Apache Hudi tables using AWS Glue custom connector](https://aws.amazon.com/blogs/big-data/writing-to-apache-hudi-tables-using-aws-glue-connector/)。
+ 有关使用 Apache Hudi、AWS Glue 和 Amazon Athena 为数据湖构建数据处理框架的文章，请参阅 [Simplify operational data processing in data lakes using AWS Glue and Apache Hudi](https://aws.amazon.com/blogs/big-data/simplify-operational-data-processing-in-data-lakes-using-aws-glue-and-apache-hudi/)。

# 查询 Apache Iceberg 表
<a name="querying-iceberg"></a>

您可以使用 Athena 对 Apache Iceberg 表进行读取、时间旅行、写入和 DDL 查询操作。

[Apache Iceberg](https://iceberg.apache.org/) 是适用于超大型分析数据集的开放表格式。Iceberg 以表的形式管理大量文件，并支持现代分析数据湖操作，例如记录级插入、更新、删除和时间旅行查询。Iceberg 规范支持表无缝发展，例如架构和分区发展，且其设计针对在 Amazon S3 上的使用进行了优化。Iceberg 还有助于在并发写入场景下保证数据的正确性。

有关 Apache Iceberg 的更多信息，请参阅 [https://iceberg.apache.org/](https://iceberg.apache.org/)。

## 注意事项和限制
<a name="querying-iceberg-considerations-and-limitations"></a>

Athena 对 Iceberg 表的支持具有以下考虑和限制：
+ **Iceberg 版本支持** – Athena 支持 Apache Iceberg 版本 1.4.2。
+ **向 Lake Formation 注册的表** — Athena 目前不支持在向 Lake Formation 注册的 Iceberg 表上进行 DDL 操作。
+ **针对信息架构的查询** — 在查询 Iceberg 表的信息架构时，Athena 将 S3 元数据用作列元数据的可信来源。这意味着列信息来自底层 S3 文件，而非目录元数据。该行为与其他表格式不同，在其他表格式中，目录元数据可能是列信息的主要来源。
+ **仅限包含 AWS Glue 目录的表** – Athena 仅支持根据由[开源 Glue 目录实施](https://iceberg.apache.org/docs/latest/aws/#glue-catalog)所定义的规范在 AWS Glue 目录上创建的 Iceberg 表。
+ **AWS Glue 仅支持表锁定** – 与支持插件自定义锁的开源 Glue 目录实施不同，Athena 仅支持 AWS Glue 乐观锁。使用 Athena 修改具有任何其他锁实施的 Iceberg 表将丢失潜在数据并中断事务。
+ **支持的文件格式** – Athena 引擎版本 3 支持以下 Iceberg 文件格式。
  + Parquet
  + ORC
  + Avro
+ **Iceberg 受限元数据** – Lake Formation 不会评估 Iceberg 元数据表。因此，如果基础表上存在任何 Lake Formation 行或单元格筛选条件，或者您无权查看基础表中的所有列，则 Iceberg 元数据表将受到限制。在这种情况下，查询 `$partitions`、`$files`、`$manifests` 和 `$snapshots` Iceberg 元数据表时将会失败并收到 `AccessDeniedException` 错误。此外，元数据列 `$path` 具有相同的 Lake Formation 限制，查询选中该列时也会失败。无论是否存在 Lake Formation 筛选条件，都可以查询所有其他元数据表。有关更多信息，请参阅 [Metadata tables](https://trino.io/docs/current/connector/iceberg.html#metadata-tables)。
+ **Iceberg v2 表** – Athena 仅在 Iceberg v2 表上进行创建和操作。有关 v1 和 v2 表之间的区别，请参阅 Apache Iceberg 文档中的[格式版本更改](https://iceberg.apache.org/spec/#appendix-e-format-version-changes)。
+ **显示没有时区的时间类型** – 没有时区类型的时间和时间戳以 UTC 格式显示。如果在时间列的筛选条件表达式中未指定时区，则使用 UTC。
+ **时间戳相关的数据精度** – 虽然 Iceberg 对时间戳数据类型支持微秒精度，但 Athena 仅对读写操作中的时间戳支持毫秒精度。在与时间相关的列中，Athena 只对在手动压缩操作过程中重写的数据保留毫秒精度。
+ **不支持的操作** – Iceberg 表格不支持以下 Athena 操作。
  + [ALTER TABLE SET LOCATION](alter-table-set-location.md)
+ **视图** – 使用 `CREATE VIEW` 创建 Athena 视图，如 [使用视图](views.md) 中所述。如果您想使用 [Iceberg 视图规范](https://github.com/apache/iceberg/blob/master/format/view-spec.md)创建视图，请联系 [athena-feedback@amazon.com](mailto:athena-feedback@amazon.com)。
+ **AWS Lake Formation 中不支持 TTF 管理命令** — 尽管您可以使用 Lake Formation 管理 Apache Iceberg、Apache Hudi 和 Linux Foundation Delta Lake 等 TransactionTable 格式（TTF）的读取访问权限，但您不能使用 Lake Formation 管理诸如 `VACUUM`、`MERGE`、`UPDATE` 或 `OPTIMIZE` 使用这些表格格式之类的操作的权限。有关 Lake Formation 与 Athena 集成的更多信息，请参阅《*AWS Lake Formation 开发人员指南*》中的[将 AWS Lake Formation 与 Amazon Athena 一起使用](https://docs.aws.amazon.com/lake-formation/latest/dg/athena-lf.html)。
+ **按嵌套字段分区** — 不支持按嵌套字段进行分区。尝试这样做会生成消息 NOT\$1SUPPORTED：不支持按嵌套字段进行分区： *column\$1name*.*nested\$1field\$1name*。
+ **不支持跳过 Amazon Glacier 对象** – 如果 Apache Iceberg 表中的对象属于 Amazon Glacier 存储类别，将 `read_restored_glacier_objects` 表属性设置为 `false` 则无效。

  例如，假设发出以下命令：

  ```
  ALTER TABLE table_name SET TBLPROPERTIES ('read_restored_glacier_objects' = 'false')
  ```

  对于 Iceberg 和 Delta Lake 表，该命令会生成错误 Unsupported table property key: read\$1restored\$1glacier\$1objects。对于 Hudi 表，`ALTER TABLE` 命令不会产生错误，但是仍无法跳过 Amazon Glacier 对象。在 `ALTER TABLE` 命令之后运行 `SELECT` 查询会继续返回所有对象。

若您希望 Athena 支持特定功能，请将反馈发送至 [athena-feedback@amazon.com](mailto:athena-feedback@amazon.com)。

**Topics**
+ [注意事项和限制](#querying-iceberg-considerations-and-limitations)
+ [创建 Iceberg 表](querying-iceberg-creating-tables.md)
+ [查询 Iceberg 表数据](querying-iceberg-table-data.md)
+ [执行时间旅行和版本旅行查询](querying-iceberg-time-travel-and-version-travel-queries.md)
+ [更新 Iceberg 表数据](querying-iceberg-updating-iceberg-table-data.md)
+ [管理 Iceberg 表](querying-iceberg-managing-tables.md)
+ [Iceberg 表架构演进](querying-iceberg-evolving-table-schema.md)
+ [对 Iceberg 表这些其他 DDL 操作](querying-iceberg-additional-operations.md)
+ [优化 Iceberg 表](querying-iceberg-data-optimization.md)
+ [查询 AWS Glue Data Catalog 实体化视图](querying-iceberg-gdc-mv.md)
+ [Athena 中支持的 Iceberg 表数据类型。](querying-iceberg-supported-data-types.md)
+ [其他资源](querying-iceberg-additional-resources.md)

# 创建 Iceberg 表
<a name="querying-iceberg-creating-tables"></a>

要创建在 Athena 中使用的 Iceberg 表，您可以使用本页中记录的 `CREATE TABLE` 语句，也可以使用 AWS Glue 爬网程序。

## 使用 CREATE TABLE 语句
<a name="querying-iceberg-creating-tables-query-editor"></a>

Athena 创建 Iceberg v2 表。有关 v1 和 v2 表之间的区别，请参阅 Apache Iceberg 文档中的[格式版本更改](https://iceberg.apache.org/spec/#appendix-e-format-version-changes)。

Athena `CREATE TABLE` 创建没有数据的 Iceberg 表。若表使用 [Iceberg 开源 Glue目录](https://iceberg.apache.org/docs/latest/aws/#glue-catalog)，则您可以直接从外部系统（例如 Apache Spark）查询表。您无需创建外部表。

**警告**  
运行 `CREATE EXTERNAL TABLE` 会导致出现错误消息 ICEBERG 表类型不支持外部关键字。

要从 Athena 创建 Iceberg 表，请将 `'table_type'` 子句中的 `'ICEBERG'` 表属性设置为 `TBLPROPERTIES`，如下语法摘要所示。

```
CREATE TABLE
  [db_name.]table_name (col_name data_type [COMMENT col_comment] [, ...] )
  [PARTITIONED BY (col_name | transform, ... )]
  LOCATION 's3://amzn-s3-demo-bucket/your-folder/'
  TBLPROPERTIES ( 'table_type' ='ICEBERG' [, property_name=property_value] )
```

有关可以在 Iceberg 表中查询的数据类型的信息，请参阅 [Athena 中支持的 Iceberg 表数据类型。](querying-iceberg-supported-data-types.md)。

### 使用分区
<a name="querying-iceberg-partitioning"></a>

要创建带有分区的 Iceberg 表，请使用 `PARTITIONED BY` 语法。必须首先在列声明中指定用于分区的列。`PARTITIONED BY` 子句中不得包括列类型。还可以在 `CREATE TABLE` 语法中定义[分区转换](https://iceberg.apache.org/spec/#partition-transforms)。要指定多个列进行分区，请使用逗号 (`,`) 字符分隔列，如以下示例所示。

```
CREATE TABLE iceberg_table (id bigint, data string, category string)
  PARTITIONED BY (category, bucket(16, id))
  LOCATION 's3://amzn-s3-demo-bucket/your-folder/'
  TBLPROPERTIES ( 'table_type' = 'ICEBERG' )
```

下表列出了可用的分区转换函数。


****  

| 函数 | 说明 | 支持的类型 | 
| --- | --- | --- | 
| year(ts) | 按年分区 | date, timestamp | 
| month(ts) | 按月分区 | date, timestamp | 
| day(ts)  | 按天分区 | date, timestamp | 
| hour(ts) | 按小时分区 | timestamp | 
| bucket(N, col) | 按哈希值 mod N 存储桶分区。这与 Hive 表的哈希分桶概念相同。 | int, long, decimal, date, timestamp, string, binary  | 
| truncate(L, col) | 按值截断为 L 分区 | int, long, decimal, string | 

Athena 支持 Iceberg 的隐藏分区。有关更多信息，请参阅 Apache Iceberg 文档中的 [Iceberg 的隐藏分区](https://iceberg.apache.org/docs/latest/partitioning/#icebergs-hidden-partitioning)。

### 指定表属性
<a name="querying-iceberg-table-properties"></a>

本部分介绍可以在 `CREATE TABLE` 语句的 `TBLPROPERTIES` 子句中指定为键值对的表属性。Athena 仅允许表属性中预定义的键值对列表用于创建或更改 Iceberg 表。下表列出了可以指定的表属性。有关压缩选项的更多信息，请参阅本文档中的 [优化 Iceberg 表](querying-iceberg-data-optimization.md)。如果您希望 Athena 支持特定的开源表配置属性，请将反馈发送至 [athena-feedback@amazon.com](mailto:athena-feedback@amazon.com)。

***format***


****  

|  |  | 
| --- |--- |
| 描述 | 文件数据格式 | 
| 允许的属性值 | 支持的文件格式和压缩组合因 Athena 引擎版本而异。有关更多信息，请参阅 [使用 Iceberg 表压缩](compression-support-iceberg.md)。 | 
| 默认值 | parquet | 

***write\$1compression***


****  

|  |  | 
| --- |--- |
| 描述 | 文件压缩编码器 | 
| 允许的属性值 | 支持的文件格式和压缩组合因 Athena 引擎版本而异。有关更多信息，请参阅 [使用 Iceberg 表压缩](compression-support-iceberg.md)。 | 
| 默认值 |  默认写入压缩因 Athena 引擎版本而异。有关更多信息，请参阅 [使用 Iceberg 表压缩](compression-support-iceberg.md)。  | 

***optimize\$1rewrite\$1data\$1file\$1threshold***


****  

|  |  | 
| --- |--- |
| 描述 | 数据优化的特定配置。若需要优化的数据文件少于给定阈值，则不会重写这些文件。这将允许积累更多的数据文件以生成更接近目标大小的文件，并跳过不必要的计算以节省成本。 | 
| 允许的属性值 | 一个正数。必须小于 50。 | 
| 默认值 | 5 | 

***optimize\$1rewrite\$1delete\$1file\$1threshold***


****  

|  |  | 
| --- |--- |
| 描述 | 数据优化的特定配置。如果与数据文件关联的删除文件少于阈值，则不会重写该数据文件。这将允许为每个数据文件累积更多的删除文件，以节省成本。 | 
| 允许的属性值 | 一个正数。必须小于 50。 | 
| 默认值 | 2 | 

***vacuum\$1min\$1snapshots\$1to\$1keep***


****  

|  |  | 
| --- |--- |
| 描述 |  在表的主分支上保留的最小快照数。 此值优先于 `vacuum_max_snapshot_age_seconds` 属性。如果剩余的最小快照比 `vacuum_max_snapshot_age_seconds` 指定的时间长，则会保留这些快照，并忽略 `vacuum_max_snapshot_age_seconds` 的值。  | 
| 允许的属性值 | 一个正数。 | 
| 默认值 | 1 | 

***vacuum\$1max\$1snapshot\$1age\$1seconds***


****  

|  |  | 
| --- |--- |
| 描述 | 要在主分支上保留的最大快照期限。如果 vacuum\$1min\$1snapshots\$1to\$1keep 指定的剩余最小快照比指定的时间长，则忽略此值。此表行为属性对应于 Apache Iceberg 配置中的 history.expire.max-snapshot-age-ms 属性。 | 
| 允许的属性值 | 一个正数。 | 
| 默认值 | 432000 秒（5 天） | 

***vacuum\$1max\$1metadata\$1files\$1to\$1keep***


****  

|  |  | 
| --- |--- |
| 描述 | 要在表的主分支上保留的先前元数据文件的最大数量。 | 
| 允许的属性值 | 一个正数。 | 
| 默认值 | 100 | 

***write\$1data\$1path\$1enabled***


****  

|  |  | 
| --- |--- |
| 描述 | 设置为 true 时，将使用 write.data.path 属性而不是已弃用的 write.object-storage.path 属性创建 Iceberg 表。使用此选项可确保与 Iceberg 1.9.0 及更高版本兼容，其不再支持已弃用的属性。 | 
| 允许的属性值 | true, false | 
| 默认值 | false | 

### CREATE TABLE 语句示例
<a name="querying-iceberg-example-create-table-statement"></a>

以下示例将创建一个包含三列的 Iceberg 表。

```
CREATE TABLE iceberg_table (
  id int,
  data string,
  category string) 
PARTITIONED BY (category, bucket(16,id)) 
LOCATION 's3://amzn-s3-demo-bucket/iceberg-folder' 
TBLPROPERTIES (
  'table_type'='ICEBERG',
  'format'='parquet',
  'write_compression'='snappy',
  'optimize_rewrite_delete_file_threshold'='10'
)
```

## 使用 CREATE TABLE AS SELECT（CTAS）
<a name="querying-iceberg-creating-tables-ctas"></a>

有关使用 `CREATE TABLE AS` 语句创建 Iceberg 表的信息，请参阅 [CREATE TABLE AS](create-table-as.md)，尤其是 [CTAS 表属性](create-table-as.md#ctas-table-properties) 部分。

## 使用 AWS Glue 爬网程序
<a name="querying-iceberg-creating-tables-crawler"></a>

您可以使用 AWS Glue 爬网程序将您的 Iceberg 表自动注册到 AWS Glue Data Catalog。如果您想从其他 Iceberg 目录迁移，可以创建和安排 AWS Glue 爬网程序，并提供 Iceberg 表所在的 Amazon S3 路径。您可以指定 AWS Glue 爬网程序可以遍历的 Amazon S3 路径的最大深度。安排 AWS Glue 爬网程序后，爬网程序会提取架构信息，并在每次运行时使用架构更改更新 AWS Glue Data Catalog。AWS Glue 爬网程序支持跨快照合并架构，并更新 AWS Glue Data Catalog 中最新的元数据文件位置。有关更多信息，请参阅 [AWS Glue 中的数据目录和爬网程序](https://docs.aws.amazon.com/glue/latest/dg/catalog-and-crawler.html)。

# 查询 Iceberg 表数据
<a name="querying-iceberg-table-data"></a>

若要查询 Iceberg 数据集，请使用标准 `SELECT` 语句，如下所示。查询遵循 Apache Iceberg [格式 v2 规范](https://iceberg.apache.org/spec/#format-versioning)，并对位置和平等删除执行读取时合并。

```
SELECT * FROM [db_name.]table_name [WHERE predicate]
```

为了优化查询时间，所有谓词都会向下推送到数据所在的位置。

有关时间旅行和版本旅行查询的信息，请参阅[执行时间旅行和版本旅行查询](querying-iceberg-time-travel-and-version-travel-queries.md)。

## 使用 Iceberg 表创建和查询视图
<a name="querying-iceberg-views"></a>

要在 Iceberg 表上创建和查询 Athena 视图，请使用 [使用视图](views.md) 中所述的 `CREATE VIEW` 视图。

示例：

```
CREATE VIEW view1 AS SELECT * FROM iceberg_table
```

```
SELECT * FROM view1 
```

如果您想使用 [Iceberg 视图规范](https://github.com/apache/iceberg/blob/master/format/view-spec.md)创建视图，请联系 [athena-feedback@amazon.com](mailto:athena-feedback@amazon.com)。

## 查询 Iceberg 表元数据
<a name="querying-iceberg-table-metadata"></a>

在 `SELECT` 查询中，您可以在 *table\$1name* 之后使用以下属性来查询 Iceberg 表元数据：
+ **\$1files** – 显示表的当前数据文件。
+ **\$1manifests** – 显示表的当前文件清单。
+ **\$1history** – 显示表的历史记录。
+ **\$1partitions** – 显示表的当前分区。
+ **\$1snapshots** – 显示表的快照。
+ **\$1refs** – 显示表的引用。

### 示例
<a name="querying-iceberg-table-metadata-syntax"></a>

以下语句列出了 Iceberg 表的文件。

```
SELECT * FROM "dbname"."tablename$files"
```

以下语句列出了 Iceberg 表的清单。

```
SELECT * FROM "dbname"."tablename$manifests" 
```

以下语句显示 Iceberg 表的历史记录。

```
SELECT * FROM "dbname"."tablename$history"
```

以下示例显示 Iceberg 表的分区。

```
SELECT * FROM "dbname"."tablename$partitions" 
```

以下示例列出了 Iceberg 表的快照。

```
SELECT * FROM "dbname"."tablename$snapshots" 
```

以下示例显示 Iceberg 表的引用。

```
SELECT * FROM "dbname"."tablename$refs" 
```

## 使用 Lake Formation 精细访问控制
<a name="querying-iceberg-working-with-lf-fgac"></a>

Athena 引擎版本 3 支持使用 Iceberg 表进行 Lake Formation 精细访问控制，包括列级和行级安全访问控制。这种访问控制适用于时间旅行查询和已执行架构发展的表。有关更多信息，请参阅 [Lake Formation 精细访问控制和 Athena 工作组](lf-athena-limitations.md#lf-athena-limitations-fine-grained-access-control)。

如果您在 Athena 外部创建了 Iceberg 表，请使用 [Apache Iceberg SDK](https://iceberg.apache.org/releases/) 版本 0.13.0 或更高版本，以便在 AWS Glue Data Catalog 中填充 Iceberg 表列信息。如果 Iceberg 表不包含 AWS Glue 中的列信息，则可以使用 Athena [ALTER TABLE SET TBLPROPERTIES](querying-iceberg-alter-table-set-properties.md) 语句或最新的 Iceberg SDK 修复表并更新 AWS Glue 中的列信息。

# 执行时间旅行和版本旅行查询
<a name="querying-iceberg-time-travel-and-version-travel-queries"></a>

每个 Apache Iceberg 表都维护所包含 Amazon S3 对象的版本控制清单。清单的早期版本可用于时间旅行和版本旅行查询。

Athena 中的时间旅行查询在 Amazon S3 中查询一致快照中截至指定日期和时间的历史数据。Athena 中的版本旅行查询在 Amazon S3 中查询指定快照 ID 以前的历史数据。

## 时间旅行查询
<a name="querying-iceberg-time-travel-queries"></a>

要运行时间旅行查询，请在 `SELECT` 语句中的表名称之后使用 `FOR TIMESTAMP AS OF timestamp`，如下例所示。

```
SELECT * FROM iceberg_table FOR TIMESTAMP AS OF timestamp
```

为旅行指定的系统时间可以是时间戳，也可以是带时区的时间戳。如果未指定，Athena 将该值视为以 UTC 时间表示的时间戳。

以下示例时间旅行查询选择指定日期和时间的 CloudTrail 数据。

```
SELECT * FROM iceberg_table FOR TIMESTAMP AS OF TIMESTAMP '2020-01-01 10:00:00 UTC'
```

```
SELECT * FROM iceberg_table FOR TIMESTAMP AS OF (current_timestamp - interval '1' day)
```

## 版本旅行查询
<a name="querying-iceberg-version-travel-queries"></a>

要执行版本旅行查询（即，查看指定版本以前的一致快照），请在 `SELECT` 语句中的表名称之后使用 `FOR VERSION AS OF version`，如下例所示。

```
SELECT * FROM [db_name.]table_name FOR VERSION AS OF version         
```

*version* 参数是与 Iceberg 表版本关联的 `bigint` 快照 ID。

以下示例版本旅行查询选择指定版本的数据。

```
SELECT * FROM iceberg_table FOR VERSION AS OF 949530903748831860
```

**注意**  
Athena 引擎版本 2 中的 `FOR SYSTEM_TIME AS OF` 和 `FOR SYSTEM_VERSION AS OF` 子句已替换为 Athena 引擎版本 3 中的 `FOR TIMESTAMP AS OF` 和 `FOR VERSION AS OF` 子句。

### 检索快照 ID
<a name="querying-iceberg-table-snapshot-id"></a>

使用 Iceberg 提供的 Java [SnapshotUtil](https://iceberg.apache.org/javadoc/1.6.0/org/apache/iceberg/util/SnapshotUtil.html) 类可以检索 Iceberg 快照 ID，如下例所示。

```
import org.apache.iceberg.Table;
import org.apache.iceberg.aws.glue.GlueCatalog;
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.iceberg.util.SnapshotUtil;

import java.text.SimpleDateFormat;
import java.util.Date;

Catalog catalog = new GlueCatalog();

Map<String, String> properties = new HashMap<String, String>();
properties.put("warehouse", "s3://amzn-s3-demo-bucket/my-folder");
catalog.initialize("my_catalog", properties);

Date date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse("2022/01/01 00:00:00");
long millis = date.getTime();

TableIdentifier name = TableIdentifier.of("db", "table");
Table table = catalog.loadTable(name);
long oldestSnapshotIdAfter2022 = SnapshotUtil.oldestAncestorAfter(table, millis);
```

## 结合使用时间旅行和版本旅行
<a name="querying-iceberg-combining-time-and-version-travel"></a>

您可以在同一查询中使用时间旅行和版本旅行语法来指定不同的时间和版本控制条件，如以下示例所示。

```
SELECT table1.*, table2.* FROM 
  [db_name.]table_name FOR TIMESTAMP AS OF (current_timestamp - interval '1' day) AS table1 
  FULL JOIN 
  [db_name.]table_name FOR VERSION AS OF 5487432386996890161 AS table2 
  ON table1.ts = table2.ts 
  WHERE (table1.id IS NULL OR table2.id IS NULL)
```

# 更新 Iceberg 表数据
<a name="querying-iceberg-updating-iceberg-table-data"></a>

您可以通过使用 `INSERT`、`UPDATE` 和 `DELETE` 查询直接在 Athena 上管理 Iceberg 表数据。每个数据管理事务都会生成一个新的快照，可以使用时间旅行查询该快照。`UPDATE` 和 `DELETE` 语句遵循 Iceberg 格式 v2 行级[位置删除](https://iceberg.apache.org/spec/#position-delete-files)规范并强制执行快照隔离。

**注意**  
Athena SQL 目前不支持“写入时复制”方法。无论指定的表属性如何，`UPDATE`、`MERGE INTO` 和 `DELETE FROM` 操作始终会使用具有位置删除功能的“读取时合并”方法。如果您设置了诸如 `write.update.mode`、`write.merge.mode` 和/或 `write.delete.mode` 等使用“写入时复制”的表属性，您的查询不会失败，因为 Athena 会忽略它们并继续使用“读取时合并”方法。

使用以下命令对 Iceberg 表执行数据管理操作。

**Topics**
+ [INSERT INTO](querying-iceberg-insert-into.md)
+ [DELETE](querying-iceberg-delete.md)
+ [UPDATE](querying-iceberg-update.md)
+ [MERGE INTO](querying-iceberg-merge-into.md)

# INSERT INTO
<a name="querying-iceberg-insert-into"></a>

将数据插入 Iceberg 表。Athena Iceberg `INSERT INTO` 收费与当前对外部 Hive 表进行 `INSERT INTO` 查询的收费一致，皆按扫描的数据量收费。要将数据插入到 Iceberg 表中，请使用以下语法，其中 *query* 可以是 `VALUES (val1, val2, ...)` 或 `SELECT (col1, col2, …) FROM [db_name.]table_name WHERE predicate`。有关 SQL 语法和语义的详细信息，请参阅 [INSERT INTO](insert-into.md)。

```
INSERT INTO [db_name.]table_name [(col1, col2, …)] query
```

以下示例将值插入到表 `iceberg_table` 中。

```
INSERT INTO iceberg_table VALUES (1,'a','c1')
```

```
INSERT INTO iceberg_table (col1, col2, ...) VALUES (val1, val2, ...)
```

```
INSERT INTO iceberg_table SELECT * FROM another_table
```

# DELETE
<a name="querying-iceberg-delete"></a>

Athena Iceberg `DELETE` 将 Iceberg 位置删除文件写入表中。这称为读取时合并删除。与写入时复制删除不同，读取时合并删除效率更高，因为其不会重写文件数据。当 Athena 读取 Iceberg 数据时，将合并 Iceberg 位置删除文件与数据文件，以生成表的最新视图。若要删除这些位置删除文件，您可以运行 [REWRITE DATA 压缩操作](querying-iceberg-data-optimization.md#querying-iceberg-data-optimization-rewrite-data-action)。`DELETE` 操作按扫描的数据量收费。有关语法，请参阅 [删除](delete-statement.md)。

以下示例从 `iceberg_table` 中删除 `c3` 作为 `category` 的值的行。

```
DELETE FROM iceberg_table WHERE category='c3'
```

# UPDATE
<a name="querying-iceberg-update"></a>

Athena Iceberg `UPDATE` 将 Iceberg 位置删除文件和新更新的行作为数据文件写入同一事务中。`UPDATE` 可视为 `INSERT INTO` 和 `DELETE` 的组合。`UPDATE` 操作按扫描的数据量收费。有关语法，请参阅 [UPDATE](update-statement.md)。

以下示例更新表 `iceberg_table` 中的指定值。

```
UPDATE iceberg_table SET category='c2' WHERE category='c1'
```

# MERGE INTO
<a name="querying-iceberg-merge-into"></a>

有条件地更新行、删除行或将行插入到 Iceberg 表中。单个语句可以组合更新、删除和插入操作。有关语法，请参阅 [MERGE INTO](merge-into-statement.md)。

**注意**  
`MERGE INTO` 是事务性的，仅支持用于 Athena 引擎版本 3 中的 Apache Iceberg 表。

以下示例从表 `t` 中删除源表 `s` 中的所有客户。

```
MERGE INTO accounts t USING monthly_accounts_update s
ON t.customer = s.customer
WHEN MATCHED
THEN DELETE
```

以下示例使用源表 `s` 中的客户信息更新目标表 `t`。如果表 `t` 与表 `s` 中的客户行匹配，则该示例会增加表 t 中的购买量。如果表 `t` 与表 `s` 中的客户行不匹配，则该示例会将表 `s` 的客户行插入到表 `t` 中。

```
MERGE INTO accounts t USING monthly_accounts_update s
    ON (t.customer = s.customer)
    WHEN MATCHED
        THEN UPDATE SET purchases = s.purchases + t.purchases
    WHEN NOT MATCHED
        THEN INSERT (customer, purchases, address)
              VALUES(s.customer, s.purchases, s.address)
```

以下示例使用源表 `s` 中的信息有条件地更新目标表 `t`。该示例删除了源地址为 Centreville 的所有匹配的目标行。对于所有其他匹配的行，该示例会添加源采购并将目标地址设置为源地址。如果目标表中没有匹配项，该示例会插入源表中的行。

```
MERGE INTO accounts t USING monthly_accounts_update s
    ON (t.customer = s.customer)
    WHEN MATCHED AND s.address = 'Centreville'
        THEN DELETE
    WHEN MATCHED
        THEN UPDATE
            SET purchases = s.purchases + t.purchases, address = s.address
    WHEN NOT MATCHED
        THEN INSERT (customer, purchases, address)
              VALUES(s.customer, s.purchases, s.address)
```

# 管理 Iceberg 表
<a name="querying-iceberg-managing-tables"></a>

Athena 支持对 Iceberg 表执行以下表 DDL 操作。

**Topics**
+ [ALTER TABLE RENAME](querying-iceberg-alter-table-rename.md)
+ [ALTER TABLE SET TBLPROPERTIES](querying-iceberg-alter-table-set-properties.md)
+ [ALTER TABLE UNSET TBLPROPERTIES](querying-iceberg-alter-table-unset-properties.md)
+ [DESCRIBE](querying-iceberg-describe-table.md)
+ [DROP TABLE](querying-iceberg-drop-table.md)
+ [SHOW CREATE TABLE](querying-iceberg-show-create-table.md)
+ [SHOW TBLPROPERTIES](querying-iceberg-show-table-properties.md)

# ALTER TABLE RENAME
<a name="querying-iceberg-alter-table-rename"></a>

重命名表。

由于 Iceberg 表的表元数据存储在 Amazon S3 中，因此您可以更新 Iceberg 托管式表的数据库和表名，而不会影响底层表信息。

## 摘要
<a name="querying-iceberg-alter-table-rename-synopsis"></a>

```
ALTER TABLE [db_name.]table_name RENAME TO [new_db_name.]new_table_name
```

## 示例
<a name="querying-iceberg-alter-table-rename-example"></a>

```
ALTER TABLE my_db.my_table RENAME TO my_db2.my_table2
```

# ALTER TABLE SET TBLPROPERTIES
<a name="querying-iceberg-alter-table-set-properties"></a>

向 Iceberg 表中添加属性并设置它们的分配值。

根据 [Iceberg 规范](https://iceberg.apache.org/#spec/#table-metadata-fields)，表属性存储在 Iceberg 表元数据文件中，而不是存储在 AWS Glue 中。Athena 不接受自定义表属性。请参阅 [指定表属性](querying-iceberg-creating-tables.md#querying-iceberg-table-properties) 部分，了解允许的键值对。您也可以使用 `ALTER TABLE SET TBLPROPERTIES` 和 `ALTER TABLE UNSET TBLPROPERTIES` 来设置或移除 `write.data.path` 和 `write.object-storage.path` Iceberg 表属性。如果您希望 Athena 支持特定的开源表配置属性，请将反馈发送至 [athena-feedback@amazon.com](mailto:athena-feedback@amazon.com)。

## 摘要
<a name="querying-iceberg-alter-table-set-properties-synopsis"></a>

```
ALTER TABLE [db_name.]table_name SET TBLPROPERTIES ('property_name' = 'property_value' [ , ... ])
```

## 示例
<a name="querying-iceberg-alter-table-set-properties-example"></a>

```
ALTER TABLE iceberg_table SET TBLPROPERTIES (
  'format'='parquet',
  'write_compression'='snappy',
  'optimize_rewrite_delete_file_threshold'='10'
)
```

以下示例会在现有 Iceberg 表上设置 `write.data.path` 属性。

```
ALTER TABLE iceberg_table SET TBLPROPERTIES (
  'write.data.path'='s3://amzn-s3-demo-bucket/your-folder/data'
)
```

# ALTER TABLE UNSET TBLPROPERTIES
<a name="querying-iceberg-alter-table-unset-properties"></a>

从 Iceberg 表中删除现有属性。

## 摘要
<a name="querying-iceberg-alter-table-unset-properties-synopsis"></a>

```
ALTER TABLE [db_name.]table_name UNSET TBLPROPERTIES ('property_name' [ , ... ])
```

## 示例
<a name="querying-iceberg-alter-table-unset-properties-example"></a>

```
ALTER TABLE iceberg_table UNSET TBLPROPERTIES ('write_compression')
```

以下示例会从 Iceberg 表中移除 `write.data.path` 属性。

```
ALTER TABLE iceberg_table UNSET TBLPROPERTIES ('write.data.path')
```

# DESCRIBE
<a name="querying-iceberg-describe-table"></a>

描述表格信息。

## 摘要
<a name="querying-iceberg-describe-table-synopsis"></a>

```
DESCRIBE [FORMATTED] [db_name.]table_name
```

指定 `FORMATTED` 选项后，输出将显示其他信息（如表位置和属性）。

## 示例
<a name="querying-iceberg-describe-table-example"></a>

```
DESCRIBE iceberg_table
```

# DROP TABLE
<a name="querying-iceberg-drop-table"></a>

删除 Iceberg 表。

**警告**  
由于 Iceberg 表在 Athena 中被视为托管式表，因此删除 Iceberg 表也会删除表中的所有数据。

## 摘要
<a name="querying-iceberg-drop-table-synopsis"></a>

```
DROP TABLE [IF EXISTS] [db_name.]table_name
```

## 示例
<a name="querying-iceberg-drop-table-example"></a>

```
DROP TABLE iceberg_table
```

# SHOW CREATE TABLE
<a name="querying-iceberg-show-create-table"></a>

显示可用于在 Athena 中重新创建 Iceberg 表的 `CREATE TABLE` DDL 语句。如果 Athena 无法重现表结构（例如，由于在表中指定了自定义表属性），则将引发不支持错误。

## 摘要
<a name="querying-iceberg-show-create-table-synopsis"></a>

```
SHOW CREATE TABLE [db_name.]table_name
```

## 示例
<a name="querying-iceberg-show-create-table-example"></a>

```
SHOW CREATE TABLE iceberg_table
```

# SHOW TBLPROPERTIES
<a name="querying-iceberg-show-table-properties"></a>

显示 Iceberg 表的一个或多个表属性。仅显示 Athena 支持的表属性。

## 摘要
<a name="querying-iceberg-show-table-properties-synopsis"></a>

```
SHOW TBLPROPERTIES [db_name.]table_name [('property_name')]
```

## 示例
<a name="querying-iceberg-show-table-properties-example"></a>

```
SHOW TBLPROPERTIES iceberg_table
```

# Iceberg 表架构演进
<a name="querying-iceberg-evolving-table-schema"></a>

Iceberg 架构更新是仅对元数据进行更改。执行架构更新时，不会更改任何数据文件。

Iceberg 格式支持以下架构发展更改：
+ **添加** – 将新列添加到表或嵌套 `struct`。
+ **删除** – 删除表或嵌套 `struct` 中的现有列。
+ **重命名** – 重命名嵌套 `struct` 中的现有列或字段。
+ **重新排序** – 更改列的顺序。
+  **类提升** – 扩大列、`struct` 字段、`map` 键、`map` 值或 `list` 元素的类型。目前，Iceberg 表支持以下案例：
  + 整数到大整数
  + 浮点到双精度
  + 提高十进制类型的精度

您可以使用本部分中的 DDL 语句来修改 Iceberg 表架构。

**Topics**
+ [ALTER TABLE ADD COLUMNS](querying-iceberg-alter-table-add-columns.md)
+ [ALTER TABLE DROP COLUMN](querying-iceberg-alter-table-drop-column.md)
+ [ALTER TABLE CHANGE COLUMN](querying-iceberg-alter-table-change-column.md)
+ [SHOW COLUMNS](querying-iceberg-show-columns.md)

# ALTER TABLE ADD COLUMNS
<a name="querying-iceberg-alter-table-add-columns"></a>

向现有 Iceberg 表添加一列或多列。

## 摘要
<a name="querying-iceberg-alter-table-add-columns-synopsis"></a>

```
ALTER TABLE [db_name.]table_name ADD COLUMNS (col_name data_type [,...])
```

## 示例
<a name="querying-iceberg-alter-table-add-columns-example"></a>

以下示例将 `string` 类型的 `comment` 列添加到 Iceberg 表中。

```
ALTER TABLE iceberg_table ADD COLUMNS (comment string)
```

以下示例将 `struct` 类型的 `point` 列添加到 Iceberg 表中。

```
ALTER TABLE iceberg_table 
ADD COLUMNS (point struct<x: double, y: double>)
```

以下示例将作为结构数组的 `points` 列添加到 Iceberg 表中。

```
ALTER TABLE iceberg_table 
ADD COLUMNS (points array<struct<x: double, y: double>>)
```

# ALTER TABLE DROP COLUMN
<a name="querying-iceberg-alter-table-drop-column"></a>

从现有 Iceberg 表中删除列。

## 摘要
<a name="querying-iceberg-alter-table-drop-column-synopsis"></a>

```
ALTER TABLE [db_name.]table_name DROP COLUMN col_name
```

## 示例
<a name="querying-iceberg-alter-table-drop-column-example"></a>

```
ALTER TABLE iceberg_table DROP COLUMN userid
```

# ALTER TABLE CHANGE COLUMN
<a name="querying-iceberg-alter-table-change-column"></a>

更改 Iceberg 表中某个列的名称、类型、顺序或注释。

**注意**  
不支持 `ALTER TABLE REPLACE COLUMNS`。由于 `REPLACE COLUMNS` 删除所有列并添加新列，因此 Iceberg 不支持该语句。`CHANGE COLUMN` 是架构发展的首选语法。

## 摘要
<a name="querying-iceberg-alter-table-change-column-synopsis"></a>

```
ALTER TABLE [db_name.]table_name
  CHANGE [COLUMN] col_old_name col_new_name column_type 
  [COMMENT col_comment] [FIRST|AFTER column_name]
```

## 示例
<a name="querying-iceberg-alter-table-change-column-example"></a>

```
ALTER TABLE iceberg_table CHANGE comment blog_comment string AFTER id
```

# SHOW COLUMNS
<a name="querying-iceberg-show-columns"></a>

显示表中的列。

## 摘要
<a name="querying-iceberg-show-columns-synopsis"></a>

```
SHOW COLUMNS (FROM|IN) [db_name.]table_name
```

## 示例
<a name="querying-iceberg-alter-table-change-column-example"></a>

```
SHOW COLUMNS FROM iceberg_table
```

# 对 Iceberg 表这些其他 DDL 操作
<a name="querying-iceberg-additional-operations"></a>

除了[Iceberg 表架构演进](querying-iceberg-evolving-table-schema.md)中描述的架构演变操作外，您还可以在 Athena 中的 Apache Iceberg 表上执行以下 DDL 操作。

## 数据库级别操作
<a name="querying-iceberg-additional-operations-database-level-operations"></a>

[DROP DATABASE](drop-database.md) 与 `CASCADE` 选项一起使用时，将删除所有 Iceberg 表数据。以下 DDL 操作不会对 Iceberg 表格产生影响。
+ [CREATE DATABASE](create-database.md)
+ [ALTER DATABASE SET DBPROPERTIES](alter-database-set-dbproperties.md)
+ [SHOW DATABASES](show-databases.md)
+ [SHOW TABLES](show-tables.md)
+ [SHOW VIEWS](show-views.md)

## 分区相关操作
<a name="querying-iceberg-additional-operations-partition-related-operations"></a>

由于 Iceberg 表使用[隐藏分区](https://iceberg.apache.org/docs/latest/partitioning/#icebergs-hidden-partitioning)，您无需直接使用物理分区。因此，Athena 中的 Iceberg 表不支持以下与分区相关的 DDL 操作：
+ [SHOW PARTITIONS](show-partitions.md)
+ [ALTER TABLE ADD PARTITION](alter-table-add-partition.md)
+ [ALTER TABLE DROP PARTITION](alter-table-drop-partition.md)
+ [ALTER TABLE RENAME PARTITION](alter-table-rename-partition.md)

如果您想在 Athena 中查看 Iceberg [分区发展](https://iceberg.apache.org/docs/latest/evolution/#partition-evolution)，请将反馈发送至[athena-feedback@amazon.com](mailto:athena-feedback@amazon.com)。

## 卸载 Iceberg 表
<a name="querying-iceberg-additional-operations-unload-iceberg-table"></a>

Iceberg 表可以卸载到 Amazon S3 上文件夹中的文件。有关信息，请参阅[UNLOAD](unload.md)。

## MSCK REPAIR
<a name="querying-iceberg-additional-operations-msck-repair"></a>

由于 Iceberg 表会跟踪表布局信息，因此像 Hive 表那样运行 [MSCK REPAIR TABLE](msck-repair-table.md) 是不必要的，也不受支持。

# 优化 Iceberg 表
<a name="querying-iceberg-data-optimization"></a>

Athena 提供多项优化功能来提升 Apache Iceberg 表的查询性能。随着数据的积累，由于文件处理开销增加以及应用存储在 Iceberg 删除文件中的行级删除的计算成本，查询效率可能会降低。为了应对这些挑战，Athena 支持手动压缩和清空运算符来优化表结构。Athena 还使用 Iceberg 统计数据来实现基于成本的查询优化，以及使用 Parquet 列索引在查询执行期间进行精确的数据修剪。这些功能协同工作，可以缩短查询执行时间，最大限度地减少数据扫描并降低成本。本主题介绍如何使用这些优化功能，保持对 Iceberg 表的高性能查询。

## OPTIMIZE
<a name="querying-iceberg-data-optimization-rewrite-data-action"></a>

`OPTIMIZE table REWRITE DATA` 压缩操作根据数据文件的大小和相关删除文件的数量将数据文件重写为更优化的布局。有关语法和表属性的详细信息，请参见 [OPTIMIZE](optimize-statement.md)。

### 示例
<a name="querying-iceberg-data-optimization-example"></a>

以下示例将删除文件合并到数据文件中，然后生成接近目标文件大小的文件，其中 `category` 的值为 `c1`。

```
OPTIMIZE iceberg_table REWRITE DATA USING BIN_PACK
  WHERE category = 'c1'
```

## VACUUM
<a name="querying-iceberg-vacuum"></a>

`VACUUM` 会执行[快照过期](https://iceberg.apache.org/docs/latest/spark-procedures/#expire_snapshots)和[孤立文件删除](https://iceberg.apache.org/docs/latest/spark-procedures/#remove_orphan_files)。这些操作会减小元数据大小，并删除不处于当前表状态且早于为表指定的保留期的文件。有关语法的详细信息，请参阅 [VACUUM](vacuum-statement.md)。

### 示例
<a name="querying-iceberg-vacuum-example"></a>

以下示例使用表属性将表 `iceberg_table` 配置为保留最近三天的数据，然后使用 `VACUUM` 使旧快照过期并从表中删除孤立文件。

```
ALTER TABLE iceberg_table SET TBLPROPERTIES (
  'vacuum_max_snapshot_age_seconds'='259200'
)

VACUUM iceberg_table
```

## 使用 Iceberg 表统计数据
<a name="querying-iceberg-data-optimization-statistics"></a>

Athena 基于成本的优化器使用 Iceberg 统计数据来生成最佳查询计划。为您的 Iceberg 表生成统计数据后，Athena 会自动使用这些信息进行关于联接排序、筛选及聚合行为的智能决策，这通常可以提升查询性能并降低成本。

使用 S3 表时，Iceberg 统计数据默认已开启。对于其他 Iceberg 表，Athena 使用表属性 `use_iceberg_statistics` 来确定是否利用统计数据进行基于成本的优化。要开始使用，请参阅《AWS Glue 用户指南》**中的[使用列统计数据优化查询性能](https://docs.aws.amazon.com//glue/latest/dg/column-statistics.html)，或者使用 [Athena 控制台](https://docs.aws.amazon.com/athena/latest/ug/cost-based-optimizer.html)基于 Iceberg 表按需生成统计数据。

## 使用 Parquet 列索引
<a name="querying-iceberg-data-optimization-parquet-column-indexing"></a>

Parquet 列索引使 Athena 能够在查询执行期间通过利用页面级最小/最大统计数据以及行组级统计数据来执行更精确的数据修剪。这使得 Athena 可以跳过行组中不必要的页面，从而显著减少扫描的数据量并提升查询性能。其最适合对已排序的列使用选择性筛选谓词的查询，能够缩短执行时间和提升数据扫描效率，同时减少 Athena 需要从 Amazon S3 读取的数据量。

如果底层 Parquet 文件中存在列索引，则 Athena 默认在 S3 表中使用 Parquet 列索引。对于其他 Iceberg 表，Athena 使用 `use_iceberg_parquet_column_index` 属性确定是否使用 Parquet 文件中的列索引。使用 AWS Glue 控制台或 `UpdateTable` API 设置此表属性。

# 查询 AWS Glue Data Catalog 实体化视图
<a name="querying-iceberg-gdc-mv"></a>

Athena 可以查询 AWS Glue Data Catalog 实体化视图。Glue Data Catalog 实体化视图将预先计算的 SQL 查询结果存储为 Apache Iceberg 表。

使用 Amazon EMR 或 AWS Glue Glue 中的 Apache Spark 创建实体化视图时，视图定义和元数据存储在 AWS Glue Data Catalog 中。预先计算的结果以 Apache Iceberg 表的形式存储在 Amazon S3 中。您可以使用标准 SQL `SELECT` 语句从 Athena 查询这些实体化视图，就像查询常规 Iceberg 表一样。

## 先决条件
<a name="querying-iceberg-gdc-mv-prerequisites"></a>

在 Athena 中查询实体化视图之前，请确保满足以下条件：
+ 实体化视图位于 AWS Glue Data Catalog 中，是使用 Apache Spark 创建的（Amazon EMR 版本 7.12.0 或更高版本，或 AWS Glue 版本 5.1 或更高版本）
+ 要在 Athena 中查询实体化视图，您需要以下 AWS Lake Formation 权限：
  + 对实体化视图的 `SELECT` 权限
  + 对实体化视图的 `DESCRIBE` 权限
  + 存储实体化视图数据的底层 Amazon S3 位置的访问权限
+ 实体化视图的底层数据存储在 Amazon S3 表类数据存储服务存储桶或 Amazon S3 通用存储桶中
+ 您可以访问包含实体化视图的 AWS Glue Data Catalog 数据库
+ 对于存储在 Amazon S3 表类数据存储服务存储桶中的实体化视图，请确保您的 IAM 角色具有访问 S3 表类数据存储服务目录所需的权限。

## 注意事项和限制
<a name="querying-iceberg-gdc-mv-considerations"></a>
+ Athena 不支持对实体化视图的以下操作：`ALTER`、`CREATE MATERIALIZED VIEW`、`REFRESH MATERIALIZED VIEW`、`DROP`、`INSERT`、`UPDATE`、`MERGE`、`DELETE`、`OPTIMIZE`、`VACUUM`。要创建实体化视图，请在 Amazon EMR 或 AWS Glue 中使用 Apache Spark。刷新操作必须通过 AWS Glue Data Catalog API 或 Apache Spark 执行。使用 Apache Spark 修改实体化视图。

## 查询实体化视图
<a name="querying-iceberg-gdc-mv-operations"></a>

Athena 将实体化视图视为用于读取操作的标准 Iceberg 表，允许您访问预先计算的数据，而无需进行特殊语法或配置更改。

要在 Athena 中查询实体化视图，请使用标准 `SELECT` 语句：

```
SELECT * FROM my_database.sales_summary_mv;
```

您可以像使用常规表一样应用筛选器、聚合和联接：

```
SELECT
  region,
  SUM(total_sales) as sales_total
FROM my_database.sales_summary_mv
WHERE year = 2025
GROUP BY region
ORDER BY sales_total DESC;
```

## 支持的操作
<a name="querying-iceberg-gdc-mv-supported"></a>

Athena 支持对实体化视图的以下操作：
+ `SELECT` 查询：使用标准 SQL `SELECT` 语句从实体化视图中读取数据
+ `DESCRIBE`：查看实体化视图的架构和元数据
+ `SHOW TABLES`：列出实体化视图以及数据库中的其他表
+ `JOIN` 操作：将实体化视图与其他表或视图联接
+ 筛选和聚合：应用 `WHERE` 子句、`GROUP BY` 和聚合函数

# Athena 中支持的 Iceberg 表数据类型。
<a name="querying-iceberg-supported-data-types"></a>

Athena 可以查询包含以下数据类型的 Iceberg 表：

```
binary
boolean
date
decimal
double
float
int
list
long
map
string
struct
timestamp without time zone
```

有关 Iceberg 表类型的更多信息，请参阅 Apache 文档中的 [Iceberg 的架构页面](https://iceberg.apache.org/docs/latest/schemas/)。

下表显示了 Athena 数据类型与 Iceberg 表数据类型之间的关系。


****  
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/querying-iceberg-supported-data-types.html)

有关 Athena 中数据类型的更多信息，请参阅 [Amazon Athena 中的数据类型](data-types.md)。

# 其他资源
<a name="querying-iceberg-additional-resources"></a>

以下文章位于《AWS 规范性指导》文档中。
+ [使用 Amazon Athena SQL 处理 Apache Iceberg 表](https://docs.aws.amazon.com/prescriptive-guidance/latest/apache-iceberg-on-aws/iceberg-athena.html) 

有关将 Athena 与 Apache Iceberg 表一起使用的深入探讨文章，请参阅 *AWS 大数据博客*。
+ [使用 Amazon DynamoDB 和 Amazon Athena 通过 Apache Iceberg 实现无服务器 CDC 流程](https://aws.amazon.com/blogs/big-data/implement-a-serverless-cdc-process-with-apache-iceberg-using-amazon-dynamodb-and-amazon-athena/) 
+ [将 Amazon Athena 与 Apache Iceberg 一起使用，加速交易数据湖上的数据科学特征工程](https://aws.amazon.com/blogs/big-data/accelerate-data-science-feature-engineering-on-transactional-data-lakes-using-amazon-athena-with-apache-iceberg/) 
+ [使用 Amazon Athena、Amazon EMR 和 AWS Glue 构建 Apache Iceberg 数据湖](https://aws.amazon.com/blogs/big-data/build-an-apache-iceberg-data-lake-using-amazon-athena-amazon-emr-and-aws-glue/) 
+ [使用 Amazon Athena 和 Apache Iceberg 在数据湖中执行更新插入](https://aws.amazon.com/blogs/big-data/perform-upserts-in-a-data-lake-using-amazon-athena-and-apache-iceberg/) 
+ [使用 Apache Iceberg、AWS Glue 构建交易数据湖，使用 AWS Lake Formation 和 Amazon Athena 构建跨账户数据共享](https://aws.amazon.com/blogs/big-data/build-a-transactional-data-lake-using-apache-iceberg-aws-glue-and-cross-account-data-shares-using-aws-lake-formation-and-amazon-athena/) 
+ [在数据湖中使用 Apache Iceberg 来支持增量数据处理](https://aws.amazon.com/blogs/big-data/use-apache-iceberg-in-a-data-lake-to-support-incremental-data-processing/) 
+ [构建与 GDPR 一致的实时 Apache Iceberg 数据湖](https://aws.amazon.com/blogs/big-data/build-a-real-time-gdpr-aligned-apache-iceberg-data-lake/) 
+ [使用 Apache Iceberg 和 AWS Glue 自动将关系源复制到交易数据湖中](https://aws.amazon.com/blogs/big-data/automate-replication-of-relational-sources-into-a-transactional-data-lake-with-apache-iceberg-and-aws-glue/) 
+ [与使用 Amazon Athena 的 Apache Iceberg 交互，以及与使用 AWS Lake Formation 的跨账户精细权限交互](https://aws.amazon.com/blogs/big-data/interact-with-apache-iceberg-tables-using-amazon-athena-and-cross-account-fine-grained-permissions-using-aws-lake-formation/) 
+ [使用 Apache Iceberg、Amazon EMR Serverless 和 Amazon Athena 构建无服务器交易数据湖](https://aws.amazon.com/blogs/big-data/build-a-serverless-transactional-data-lake-with-apache-iceberg-amazon-emr-serverless-and-amazon-athena/) 