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

Amazon Athena 中的数据类型

运行 CREATE TABLE 时,您可以指定列名以及每列可以包含的数据类型。所创建的表存储在 Amazon Glue Data Catalog 中。

为了促进与其他查询引擎的互操作性,Athena 对 DDL 语句(例如 CREATE TABLE)使用 Apache Hive 数据类型名称。对于像 SELECTCTASINSERT INTO 这样的 DML 查询,Athena 则使用 Trino 数据类型名称。下表显示了 Athena 支持的数据类型。如果 DDL 和 DML 类型在名称、可用性或语法方面存在差异,则会显示在不同的列中。

DDL DML 描述
BOOLEAN 值包括 truefalse
TINYINT 一个 8 位有符号的整数,采用二进制补码格式,最小值为 -27,最大值为 27-1。
SMALLINT 一个 16 位有符号的整数,采用二进制补码格式,最小值为 -215,最大值为 215-1。
INT,INTEGER 一个 32 位有符号的值,采用二进制补码格式,最小值为 -231,最大值为 231-1。
BIGINT 一个 64 位有符号的整数,采用二进制补码格式,最小值为 -263,最大值为 263-1。
FLOAT REAL 一个 32 位有符号的单精度浮点数。范围为 1.40129846432481707e-45 至 3.40282346638528860e+38,可以为正数,也可以为负数。遵循 IEEE 浮点运算标准(IEEE 754)。
DOUBLE 一个 64 位有符号的双精度浮点数。范围为 4.94065645841246544e-324d 至 1.79769313486231570e+308d,可以为正数,也可以为负数。遵循 IEEE 浮点运算标准(IEEE 754)。
DECIMAL(precision, scale) precision 是总位数;scale(可选)是小数部分的位数,默认值为 0。例如,使用以下类型定义:decimal(11,5)decimal(15)。最大精度值为 38,最大标度值为 38。
CHAR、CHAR(length)

固定长度字符数据,指定长度介于 1 到 255 之间,例如 char(10)。如果指定了 length,则读取字符串时,字符串将按指定长度进行截断。如果底层数据字符串较长,则底层数据字符串将保持不变。

有关更多信息,请参阅 CHAR Hive 数据类型

string VARCHAR 长度可变的字符数据。
VARCHAR(length) 具有最大读取长度的长度可变的字符数据。读取字符串时,字符串将按指定长度进行截断。如果底层数据字符串较长,则底层数据字符串将保持不变。
BINARY VARBINARY 长度可变的二进制数据。
TIME 一天中的某个时间,精确到毫秒。
不可用 TIME(precision) 一天中的某个时间,具有具体精度。TIME(3) 等同于 TIME
不可用 带时区的时间 某个时区一天中的某个时间。应将时区指定为 UTC 的偏移量。
DATE 包含年、月、日的某个日历日期。
TIMESTAMP TIMESTAMP、TIMESTAMP WITHOUT TIME ZONE 某个日历日期一天中的某个时间,精确到毫秒。
不可用 TIMESTAMP(precision)、TIMESTAMP(precision) WITHOUT TIME ZONE 某个日历日期一天中的某个时间,具有具体精度。TIMESTAMP(3) 等同于 TIMESTAMP
不可用 TIMESTAMP(有时区) 在某个时区中,某个日历日期一天中的某个时间。可以将时区指定为 UTC 的偏移量、IANA 时区名称或使用 UTC、UT、Z 或 GMT。
不可用 TIMESTAMP(precision) WITH TIME ZONE 在某个时区中,某个日历日期一天中的某个时间,具有具体精度。
不可用 INTERVAL YEAR TO MONTH 间隔为一个月或数个整月
不可用 INTERVAL DAY TO SECOND 间隔为一或数秒/分钟/小时/日
ARRAY<element_type> ARRAY[element_type] 值的数组。所有值的类型必须相同。
MAP<key_type, value_type> MAP(key_type, value_type) 可以通过键查找值的映射。所有键的值必须相同,并且所有值必须相同。
STRUCT<field_name_1:field_type_1, field_name_2:field_type_2, …> ROW(field_name_1 field_type_1, field_name_2 field_type_2, …) 包含命名字段及其值的数据结构。
不可用 JSON JSON 值类型,可以是 JSON 对象、JSON 数组、JSON 数字、JSON 字符串、truefalsenull
不可用 UUID UUID,全称通用唯一标识符。
不可用 IPADDRESS IPv4 或 IPv6 地址。
不可用 HyperLogLog 这些数据类型支持近似的函数内部构成。有关各种类型的更多信息,请访问 Trino 文档中相应条目的链接。
P4HyperLogLog
SetDigest
QDigest
TDigest

数据类型示例

下表列示了 DML 数据类型的示例文字。

数据类型 示例
BOOLEAN

true

false

TINYINT

TINYINT '123'

SMALLINT

SMALLINT '123'

INT,INTEGER

123456790

BIGINT

BIGINT '1234567890'

2147483648

REAL

'123456.78'

DOUBLE

1.234

DECIMAL(precision, scale)

DECIMAL '123.456'

CHAR、CHAR(length)

CHAR 'hello world', CHAR 'hello ''world''!'

VARCHAR、VARCHAR(length)

VARCHAR 'hello world', VARCHAR 'hello ''world''!'

VARBINARY

X'00 01 02'

TIME、TIME(precision)

TIME '10:11:12', TIME '10:11:12.345'

带时区的时间

TIME '10:11:12.345 -06:00'

DATE

DATE '2024-03-25'

TIMESTAMP、TIMESTAMP WITHOUT TIME ZONE、TIMESTAMP(precision)、TIMESTAMP(precision) WITHOUT TIME ZONE

TIMESTAMP '2024-03-25 11:12:13', TIMESTAMP '2024-03-25 11:12:13.456'

TIMESTAMP WITH TIME ZONE、TIMESTAMP(precision) WITH TIME ZONE

TIMESTAMP '2024-03-25 11:12:13.456 Europe/Berlin'

INTERVAL YEAR TO MONTH

INTERVAL '3' MONTH

INTERVAL DAY TO SECOND

INTERVAL '2' DAY

ARRAY[element_type]

ARRAY['one', 'two', 'three']

MAP(key_type, value_type)

MAP(ARRAY['one', 'two', 'three'], ARRAY[1, 2, 3])

请注意,映射根据键的数组和值的数组创建。

ROW(field_name_1 field_type_1, field_name_2 field_type_2, …)

ROW('one', 'two', 'three')

请注意,以这种方式创建的行并无列名。要添加列名,可以使用 CAST,如下例所示:

CAST(ROW(1, 2, 3) AS ROW(one INT, two INT, three INT))
JSON

JSON '{"one":1, "two": 2, "three": 3}'

UUID

UUID '12345678-90ab-cdef-1234-567890abcdef'

IPADDRESS

IPADDRESS '10.0.0.1'

IPADDRESS '2001:db8::1'

数据类型的注意事项

大小限制

对于没有指定大小限制的数据类型,请记住,对于单行中的所有数据,实际限制为 32MB。有关更多信息,请参阅Amazon Athena 中 SQL 查询的注意事项和限制中的Row or column size limitation

CHAR 和 VARCHAR

CHAR(n) 值始终具有 n 个字符数。例如,若将 'abc' 强制转换为 CHAR(7),则会添加 4 个尾随空格。

CHAR 值的比较包括前导空格和尾随空格。

如果指定了 CHARVARCHAR 的长度,则读取字符串时,字符串将按指定长度进行截断。如果底层数据字符串较长,则底层数据字符串将保持不变。

要对 CHARVARCHAR 中的单引号进行转义,请额外使用一个单引号。

要在 DML 查询中将非字符串数据类型转换为字符串,请强制转换为 VARCHAR 数据类型。

要使用 substr 函数从 CHAR 数据类型返回指定长度的子字符串,就必须先将 CHAR 值强制转换为 VARCHAR。在以下示例中,col1 使用了 CHAR 数据类型。

substr(CAST(col1 AS VARCHAR), 1, 4)

DECIMAL

要在 SELECT 查询中将十进制值指定为文字(例如选择具有特定十进制值的行时),您可以指定 DECIMAL 类型,并在查询中将该十进制值列为单引号中的文字,如下例所示:

SELECT * FROM my_table WHERE decimal_value = DECIMAL '0.12'
SELECT DECIMAL '44.6' + DECIMAL '77.2'

处理时间戳数据

本节介绍在 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 的时间类型)。

    注意

    OpenCSVSerDe 时间戳是个例外,必须编码为毫秒解析的 UNIX 纪元。

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

数据的创建者必须确保分区值与分区内的数据一致。例如,若数据具有 timestamp 属性,并且使用 Firehose 将数据加载到 Amazon S3 中,则您必须使用动态分区,因为 Firehose 的默认分区基于挂钟。

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

出于性能考虑,最好将 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 表