动态 ID 分区 - Amazon Athena
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

动态 ID 分区

当数据按高基数属性分区时,或者无法事先知道这些值时,您可以使用 injected 投影类型。此类属性的示例包括用户名以及设备或产品的 ID。当您使用 injected 投影类型配置分区键时,Athena 使用查询本身的值来计算要读取的分区集。

如果某个表具有通过 injected 投影类型配置的分区键,则要使 Athena 能够在该表上运行查询,必须满足以下条件:

  • 查询必须包括至少一个分区键值。

  • 值必须是无需读取任何数据即可评估的文字或表达式。

只要其中一个条件不满足,查询就会失败,并显示以下错误:

CONSTRAINT_VIOLATION:对于注入的投影分区列 column_name,WHERE 子句必须仅包含静态相等条件,并且必须至少存在一个此类条件。

使用 injected 投影类型

设想您的数据集包含来自 IoT 设备的事件,并按设备的 ID 进行分区。该数据集具有以下特征:

  • 设备 ID 随机生成。

  • 新设备经常预置。

  • 目前有数十万台设备,将来会有数百万台。

使用传统的元数据存储很难管理此数据集。难以确保数据存储与元存储之间保持分区同步,而且在查询规划期间筛选分区可能很慢。但是,如果您将表配置为使用分区投影并使用 injected 投影类型,您会获得两个优势:您不必在元存储中管理分区,并且您的查询不必查找分区元数据。

以下 CREATE TABLE 示例会为刚刚描述的设备事件数据集创建一个表。该表使用注入投影类型。

CREATE EXTERNAL TABLE device_events ( event_time TIMESTAMP, data STRING, battery_level INT ) PARTITIONED BY ( device_id STRING ) LOCATION "s3://DOC-EXAMPLE-BUCKET/prefix/" TBLPROPERTIES ( "projection.enabled" = "true", "projection.device_id.type" = "injected", "storage.location.template" = "s3://DOC-EXAMPLE-BUCKET/prefix/${device_id}" )

以下示例查询会查找在 12 小时内从三台特定设备收到的事件数。

SELECT device_id, COUNT(*) AS events FROM device_events WHERE device_id IN ( '4a770164-0392-4a41-8565-40ed8cec737e', 'f71d12cf-f01f-4877-875d-128c23cbde17', '763421d8-b005-47c3-ba32-cc747ab32f9a' ) AND event_time BETWEEN TIMESTAMP '2023-11-01 20:00' AND TIMESTAMP '2023-11-02 08:00' GROUP BY device_id

当您运行此查询时,Athena 会看到 device_id 分区键的三个值,并使用这些值来计算分区位置。Athena 使用 storage.location.template 属性的值来生成以下位置:

  • s3://DOC-EXAMPLE-BUCKET/prefix/4a770164-0392-4a41-8565-40ed8cec737e

  • s3://DOC-EXAMPLE-BUCKET/prefix/f71d12cf-f01f-4877-875d-128c23cbde17

  • s3://DOC-EXAMPLE-BUCKET/prefix/763421d8-b005-47c3-ba32-cc747ab32f9a

如果您在分区投影配置中省略了 storage.location.template 属性,Athena 会使用 Hive 风格分区,根据 LOCATION 中的值(例如,s3://DOC-EXAMPLE-BUCKET/prefix/device_id=4a770164-0392-4a41-8565-40ed8cec737e)投影分区位置。