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

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

Amazon Athena 中的数据类型

运行 CREATE TABLE 时,您可以指定列名和每列可以包含的数据类型。Athena 支持下面列出的数据类型。有关 JDBC 驱动程序在 Athena、JDBC 和 Java 之间支持的数据类型映射的信息,请参阅《JDBC 驱动程序安装和配置指南》中的数据类型一节。有关 ODBC 驱动程序在 Athena 和 SQL 之间支持的数据类型映射的信息,请参阅《ODBC 驱动程序安装和配置指南》中的数据类型一节。

  • boolean – 值为 truefalse

  • tinyint – 一个 8 位有符号的整数,采用二进制补码格式,最小值为 -27,最大值为 27-1。

  • smallint – 一个 16 位有符号的整数,采用二进制补码格式,最小值为 -215,最大值为 215-1。

  • intinteger – Athena 根据查询类型使用不同的整数表达式。

    • int – 在数据定义语言 (DDL) 查询(如 CREATE TABLE)中,使用 int 数据类型。

    • integer – 在 DML 查询(如 SELECT * FROM)中,使用 integer 数据类型。integer 以二进制补码格式表示为 32 位有符号值,最小值为 -231,最大值为 231-1。

      • 为确保与业务分析应用程序兼容,JDBC 驱动程序返回 integer 类型。

  • bigint – 一个 64 位有符号的整数,采用二进制补码格式,最小值为 -263,最大值为 263-1。

  • double – 64 位有符号的双精度浮点数。范围为 4.94065645841246544e-324d 至 1.79769313486231570e+308d,正或负。double 遵循 IEEE 浮点算法标准 (IEEE 754)。

  • float – 32 位有符号的单精度浮点数。范围为 1.40129846432481707e-45 至 3.40282346638528860e+38,正或负。float 遵循 IEEE 浮点算法标准 (IEEE 754)。相当于 Presto 中的 real。在 Athena 中,在 CREATE TABLE 等 DDL 语句中使用 float,在 SELECT CAST 等 SQL 函数中使用 real。Amazon Glue 爬网程序以 float 返回值, Athena 将内部翻译 realfloat 类型(请参阅 2018 年 6 月 5 日 发布说明)。

  • decimal(precision, scale)precision 是总位数。scale(可选)是小数部分的位数,默认值为 0。例如,使用以下类型定义:decimal(11,5)decimal(15)。最大精度值为 38,最大标度值为 38。

    要将十进制值指定为文字(例如在查询 DDL 表达式中选择具有特定十进制值的行时),请指定 decimal 类型定义,并在查询中将十进制值列为文字(带单引号),如下例所示:decimal_value = decimal '0.12'

  • char – 固定长度字符数据,具有介于 1 和 255 之间的指定长度,例如 char(10)。有关更多信息,请参阅 CHAR Hive 数据类型

    注意

    要使用 substr 函数从 char 数据类型返回指定长度的子字符串,您必须先将 char 值转换为 varchar,如以下示例所示。

    substr(cast(col1 as varchar), 1, 4)
  • varchar – 可变长度字符数据,具有介于 1 和 65535 之间的指定长度,例如 varchar(10)。有关更多信息,请参阅 VARCHAR Hive 数据类型

  • string – 用单引号或双引号括起的字符串文本。有关更多信息,请参阅 STRING Hive 数据类型

    注意

    在 Athena 中,无法将非字符串数据类型强制转换为 string;而是将这些数据类型强制转换为 varchar

  • ipaddress— 表示 DML 查询中的 IP 地址。不支持 DDL。有关更多信息,请参阅 IP 地址

  • binary – 用于 Parquet 中的数据。

  • date – ISO 格式的日期,例如 YYYY-MM-DD。例如,date '2008-09-15'。一个例外是 OpenCSVSerDe,它使用自 1970 年 1 月 1 日以来经过的天数。有关更多信息,请参阅 用于处理 CSV 的 OpenCSVSerDe

  • timestamp – 使用 java.sql.Timestamp 兼容格式的瞬间日期和时间最多可达毫秒级的最大分辨率,例如 yyyy-MM-dd HH:mm:ss[.f...]。例如,timestamp '2008-09-15 03:04:05.324'。一个例外是 OpenCSV SerDe,它使用 UNIX 数字格式timestamp的数据(例如)。1579059880000

    有关使用时间戳的更多信息,请参阅文档下文的 处理时间戳数据

  • array<data_type> – 给定组件类型的数组。

    示例

    CREATE TABLE table array_table (c1 array<integer>) LOCATION '...'; INSERT INTO array_table values(ARRAY[1,2,3]);
  • map<primitive_type, data_type> – 给定组件类型之间的映射。

    示例

    CREATE TABLE map_table(c1 map<string, integer>) LOCATION '...'; INSERT INTO map_table values(MAP(ARRAY['foo', 'bar'], ARRAY[1, 2]));
  • struct<col_name : data_type, ...> – 不同组件类型的元素集合。

    示例

    CREATE TABLE struct_table(c1 struct<name:varchar(10), age:integer>) LOCATION '...'; INSERT INTO struct_table SELECT CAST(ROW('Bob', 38) AS ROW(name VARCHAR(10), age INTEGER));

处理时间戳数据

本节介绍在 Athena 中处理时间戳数据的一些注意事项。

注意

Athena 引擎版本 2 和 Athena 引擎版本 3 对时间戳的处理方式有所改变。有关 Athena 引擎版本 3 中可能出现的时间戳相关错误以及建议的解决方案的信息,请参阅 Athena 引擎版本 3 参考中的 时间戳更改

向 Amazon S3 对象写入时间戳数据的格式

向 Amazon S3 对象写入时间戳数据的格式取决于列数据类型和您使用的SerDe库

  • 如果您的表列类型为 DATE,Athena 预计数据的相应列或属性是 ISO 格式 YYYY-MM-DD 的字符串,或者是内置的日期类型(例如 Parquet 或 ORC 的日期类型)。

  • 如果您的表列类型为 TIME,Athena 预计数据的相应列或属性是 ISO 格式 HH:MM:SS 的字符串,或者是内置的时间类型(例如 Parquet 或 ORC 的日期类型)。

  • 如果您的表列类型为 TIMESTAMP,Athena 预计数据的相应列或属性是 YYYY-MM-DD HH:MM:SS.SSS 格式的字符串(注意日期和时间之前的空格),或者是内置的时间类型(例如 Parquet、ORC 或 Ion 的时间类型)。

    注意

    OpenCSV SerDe 时间戳是个例外,必须编码为毫秒分辨率的 UNIX 时代。

确保时间分区数据与记录中的时间戳字段相匹配

数据的创建者必须确保分区值与分区内的数据一致。例如,如果您的数据具有timestamp属性,并且您使用 Kinesis Data Firehose 将数据加载到 Amazon S3 中,则必须使用动态分区,因为 Kinesis Data Firehose 的默认分区是。 wall-clock-based

使用字符串作为分区键的数据类型

出于性能考虑,最好将 STRING 用作分区键的数据类型。尽管在您使用 DATE 类型时,Athena 会将 YYYY-MM-DD 格式的分区值识别为日期,但这可能会导致性能不佳。因此,我们建议您为分区键改用 STRING 数据类型。

如何为同时按时间分区的时间戳字段编写查询

如何为按时间分区的时间戳字段编写查询取决于要查询的表的类型。

Hive 表

由于 Athena 中最常用的 Hive 表,因此查询引擎对列和分区键之间的关系一无所知。因此,您必须始终在查询中为列和分区键添加谓词。

例如,假设您有一 event_time 列和一个 event_date 分区键,并且想要查询 23:00 到 03:00 之间的事件。在本例中,您必须在查询中同时包含列和分区键的谓词,如下例所示。

WHERE event_time BETWEEN start_time AND end_time AND event_date BETWEEN start_time_date AND end_time_date

Iceberg 表

使用 Iceberg 表,您可以使用计算出的分区值,从而简化查询。例如,假设您的 Iceberg 表是使用如下的 PARTITIONED BY 子句创建的:

PARTITIONED BY (event_date month(event_time))

在本例中,查询引擎会根据 event_time 谓词的值自动修剪分区。因此,您的查询只需要为 event_time 指定谓词,如以下示例所示。

WHERE event_time BETWEEN start_time AND end_time

有关更多信息,请参阅 创建 Iceberg 表