Flink Table & SQL 数据类型
主要引用官方文档 https://ci.apache.org/projects/flink/flink-docs-release-1.13/docs/dev/table/types/
在 Flink 1.9 之前,Flink 的 Table 和 SQL API 数据类型与 Flink 的 TypeInformation
紧密关联。TypeInformation
用于 DataStream 和 DataSet API 中,足以描述在分布式环境中基于 JVM 的对象序列化和反序列化所需的所有信息。
但是,TypeInformation 并不是为独立于 JVM Class 的逻辑类型,很难将 SQL 标准类型映射 TypeInformation
抽象。此外,有一些类型并不兼容 SQL 并且引入的时候没有长远规划。
从 Flink 1.9 开始,Table&SQL API 将获得一种新的类型系统作为长期解决方案,用来保障 API 稳定性和 SQL 标准兼容性。
数据类型(Data Type)
数据类型描述 Table 变成环境中值的逻辑类型,可以被用来声明操作的输入和输出类型。
Flink 的数据类型和 SQL标准的数据类型类似,并且支持 null/not null 属性,一些例子(下文有完整的数据类型列表):
INT
INT NOT NULL
INTERVAL DAY TO SECOND(3)
ROW<myField ARRAY<BOOLEAN>, myOtherField TIMESTAMP(3)>
预定义数据类型
Character Strings(字符串)
CHAR
固定长度字符串的数据类型
CHAR
CHAR(n)
其中 n 表示字符数量。n 的值必须在 1 和 2,147,483,647 之间(含边界值)。如果未指定长度,n 等于 1。
VARCHAR / STRING
可变长度字符串的数据类型
VARCHAR
VARCHAR(n)
STRING
其中 n 表示最大的字符数量。n 的值必须在 1 和 2,147,483,647 之间(含边界值)。如果未指定长度,n 等于 1。
STRING
等价于 VARCHAR(2147483647)
。
Binary Strings(二进制字符串)
BINARY
固定长度二进制字符串的数据类型(字节序列)。
BINARY
BINARY(n)
其中 n 是字节数量。n 的值必须在 1 和 2,147,483,647 之间(含边界值)。如果未指定长度,n 等于 1。
VARBINARY / BYTES
可变长度二进制字符串的数据类型(字节序列)。
VARBINARY
VARBINARY(n)
BYTES
其中 n 是最大的字节数量。n 的值必须在 1 和 2,147,483,647 之间(含边界值)。如果未指定长度,n 等于 1。
BYTES
等价于 VARBINARY(2147483647)
。
Exact Numerics(精确数值)
DECIMAL
精度和小数位数固定的十进制数字的数据类型。
DECIMAL
DECIMAL(p)
DECIMAL(p, s)
DEC
DEC(p)
DEC(p, s)
NUMERIC
NUMERIC(p)
NUMERIC(p, s)
其中 p 是数字的位数(精度),s 是数字中小数点右边的位数(尾数)。p 的值必须介于 1 和 38 之间(含边界值)。s 的值必须介于 0 和 p 之间(含边界值)。其中 p 的缺省值是 10,s 的缺省值是 0。
NUMERIC
和 DEC
都等价于这个类型。
TINYINT
1 字节有符号整数的数据类型,其值从 -128 to 127。
TINYINT
SMALLINT
2 字节有符号整数的数据类型,其值从 -32,768 到 32,767。
SMALLINT
INT
4 字节有符号整数的数据类型,其值从 -2,147,483,648 到 2,147,483,647。
INT
INTEGER
INTEGER
等价于此类型。
BIGINT
8 字节有符号整数的数据类型,其值从 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。
BIGINT
Approximate Numerics(近似数值)
FLOAT
4 字节单精度浮点数的数据类型。
与 SQL 标准相比,该类型不带参数。
FLOAT
DOUBLE
8 字节双精度浮点数的数据类型。
DOUBLE
DOUBLE PRECISION
DOUBLE PRECISION
等价于此类型。
Date and Time(日期和时间)
DATE
日期的数据类型由 year-month-day
组成,范围从 0000-01-01 到 9999-12-31。
与 SQL 标准相比,年的范围从 0000 开始。
DATE
TIME
不带时区的时间数据类型,由 hour:minute:second[.fractional]
组成,精度达到纳秒,范围从 00:00:00.000000000 到 23:59:59.999999999。
与 SQL 标准相比,不支持 leap seconds(23:59:60 和 23:59:61),语义上更接近于 java.time.LocalTime
。没有提供带有时区的时间。
TIME
TIME(p)
其中 p 是秒的小数部分的位数(精度)。p 的值必须介于 0 和 9 之间(含边界值)。如果未指定精度,则 p 等于 0。
TIMESTAMP
不带时区的时间戳数据类型,由 year-month-day hour:minute:second[.fractional]
组成,精度达到纳秒,范围从 0000-01-01 00:00:00.000000000 到 9999-12-31 23:59:59.999999999。
与 SQL 标准相比,不支持 leap seconds(23:59:60 和 23:59:61),语义上更接近于 java.time.LocalDateTime
。
<u>不支持和 BIGINT(JVM long 类型)互相转换</u>,此类型是无时区的。
对于语义上更接近于 java.time.Instant
的需求请使用 TIMESTAMP WITH LOCAL TIME ZONE
。
TIMESTAMP
TIMESTAMP(p)
TIMESTAMP WITHOUT TIME ZONE
TIMESTAMP(p) WITHOUT TIME ZONE
其中 p 是秒的小数部分的位数(精度)。p 的值必须介于 0 和 9 之间(含边界值)。如果未指定精度,则 p 等于 6。
TIMESTAMP(p) WITHOUT TIME ZONE
等价于此类型。
TIMESTAMP WITH TIME ZONE
带有时区的时间戳数据类型,由 year-month-day hour:minute:second[.fractional] zone
组成,精度达到纳秒,范围从 0000-01-01 00:00:00.000000000 +14:59 到 9999-12-31 23:59:59.999999999 -14:59。
与 SQL 标准相比,不支持 leap seconds(23:59:60 和 23:59:61),语义上更接近于 java.time.OffsetDateTime
。
与 TIMESTAMP WITH LOCAL TIME ZONE
(见下文)相比,时区偏移信息物理存储在每个数据中。单独用于每次计算、可视化或者与外部系统的通信。
TIMESTAMP WITH TIME ZONE
TIMESTAMP(p) WITH TIME ZONE
其中 p 是秒的小数部分的位数(精度)。p 的值必须介于 0 和 9 之间(含边界值)。如果未指定精度,则 p 等于 6。
TIMESTAMP WITH LOCAL TIME ZONE
带有本地时区的时间戳数据类型,由 year-month-day hour:minute:second[.fractional] zone
组成,精度达到纳秒,范围从 0000-01-01 00:00:00.000000000 +14:59 到 9999-12-31 23:59:59.999999999 -14:59。
与 SQL 标准相比,不支持 leap seconds(23:59:60 和 23:59:61),语义上更接近于 java.time.OffsetDateTime
。
与 TIMESTAMP WITH TIME ZONE
相比,<u>时区偏移信息并非物理存储在每个数据中</u>。相反,此类型在 Table 编程环境的 UTC 时区中采用 java.time.Instant
语义。<u>每个数据都在当前会话中配置的本地时区中进行解释</u>,以便用于计算和可视化。
此类型允许根据配置的会话时区来解释 UTC 时间戳,可以区分时区无关和时区相关的时间戳类型。
TIMESTAMP WITH LOCAL TIME ZONE
TIMESTAMP(p) WITH LOCAL TIME ZONE
TIMESTAMP_LTZ
TIMESTAMP_LTZ(p)
其中 p 是秒的小数部分的位数(精度)。p 的值必须介于 0 和 9 之间(含边界值)。如果未指定精度,则 p 等于 6。
TIMESTAMP_LTZ
等价于此类型。
INTERVAL YEAR TO MONTH
一组由 Year-Month Interval
组成的数据类型,其范围从 -9999-11 到 +9999-11,可以表达:
- 间隔年份、月份
INTERVAL YEAR
INTERVAL YEAR(p)
INTERVAL YEAR(p) TO MONTH
INTERVAL MONTH
其中 p 是年数(年精度)的位数。p 的值必须介于 1 和 4 之间(含边界值)。如果未指定年精度,p 则等于 2。
示例
时间间隔字面量 | 说明 |
---|---|
INTERVAL '3' YEAR | 时间间隔为3年 |
INTERVAL '3' MONTH | 时间间隔为3个月 |
INTERVAL '3-4' YEAR TO MONTH | 时间间隔为3年4个月 |
INTERVAL DAY TO SECOND
一组由 Day-Time Interval
组成的数据类型。时间间隔由 +days hours:minutes:seconds.fractional
组成,其范围从 -999999 23:59:59.999999999 到 +999999 23:59:59.999999999,可以表达:
- 间隔天、小时、分钟、秒
INTERVAL DAY
INTERVAL DAY(p1)
INTERVAL DAY(p1) TO HOUR
INTERVAL DAY(p1) TO MINUTE
INTERVAL DAY(p1) TO SECOND(p2)
INTERVAL HOUR
INTERVAL HOUR TO MINUTE
INTERVAL HOUR TO SECOND(p2)
INTERVAL MINUTE
INTERVAL MINUTE TO SECOND(p2)
INTERVAL SECOND
INTERVAL SECOND(p2)
其中 p1 是天数(天精度)的位数,p2 是秒的小数部分的位数(小数精度)。p1 的值必须介于 1 和之间 6(含边界值),p2 的值必须介于 0 和之间 9(含边界值)。如果 p1 未指定值,则缺省等于 2,如果 p2 未指定值,则缺省等于 6。
示例
时间间隔字面量 | 说明 |
---|---|
INTERVAL '3' DAY | 时间间隔为3天 |
INTERVAL '2' HOUR | 时间间隔为2小时 |
INTERVAL '25' MINUTE | 时间间隔为25分钟 |
INTERVAL '45' SECOND | 时间间隔为45秒 |
INTERVAL '3 02' DAY TO HOUR | 时间间隔为3天零2小时 |
INTERVAL '3 02:25' DAY TO MINUTE | 时间间隔为3天零2小时25分 |
INTERVAL '3 02:25:45' DAY TO SECOND | 时间间隔为3天零2小时25分45秒 |
INTERVAL '02:25' HOUR TO MINUTE | 时间间隔为2小时25分 |
INTERVAL '02:25:45' HOUR TO SECOND | 时间间隔为2小时25分45秒 |
INTERVAL '25:45' MINUTE TO SECOND | 时间间隔为25分45秒 |
Constructured Data Types(结构化数据类型)
ARRAY
具有相同子类型元素的数组的数据类型。
与 SQL 标准相比,<u>无法指定数组的最大长度</u>,而是被固定为 2,147,483,647。另外,任何有效类型都可以作为子类型。
ARRAY<t>
t ARRAY
此类型用 ARRAY<t>
声明,其中 t 是所包含元素的数据类型。
t ARRAY
等价于 ARRAY<t>
类型。
MAP
将键(包括 NULL
)映射到值(包括 NULL
)的关联数组的数据类型。<u>不能包含重复的键</u>;
元素类型没有限制;<u>确保唯一性是用户的责任</u>。
Map 类型是 SQL 标准的扩展。
MAP<kt, vt>
其中 kt 是键的数据类型,vt 是值的数据类型。
MULTISET
多重集合的数据类型。允许每个具有公共子类型的元素有多个实例(区别于 SET)。
元素类型没有限制;
MULTISET<t>
t MULTISET
其中 t 是所包含元素的数据类型。
t MULTISET
等价于 MULTISET<t>
类型
ROW
字段序列(A sequence of fields)的数据类型。字段由字段名称、字段类型和可选的描述组成。
Table row 是一种特殊的 Row 类型。行的每一列,对应 Row 类型中一个相同位置的字段。
Row 类型类似于其他非标准兼容框架中的 STRUCT
类型。
ROW<n0 t0, n1 t1, ...>
ROW<n0 t0 'd0', n1 t1 'd1', ...>
ROW(n0 t0, n1 t1, ...>
ROW(n0 t0 'd0', n1 t1 'd1', ...)
其中 n 是唯一的字段名称,t 是字段的逻辑类型,d 是字段的描述。
Other Data Types(其他数据类型)
BOOLEAN
(可能)具有 TRUE
、FALSE
和 UNKNOWN
三值逻辑的布尔数据类型。
BOOLEAN
RAW
任意序列化类型的数据类型。此类型对于 Flink Table 来讲是一个黑盒子,仅在跟外部交互时被反序列化。
RAW('class', 'snapshot')
其中 class 是原始类,snapshot 是 Base64 编码的序列化的 TypeSerializerSnapshot
。通常,类型字符串不是直接声明的,而是在持久化类型时生成的。
在 API 中,可以通过直接提供 Class + TypeSerializer 或通过传递 TypeInformation
并让框架从那里提取 Class + TypeSerializer 来声明 RAW 类型。
NULL
表示空类型 NULL
值的数据类型。
NULL
类型除 NULL
值以外没有其他值,这种类型在实践中不是很有用。
NULL
User-Defined Data Types(用户自定义数据类型)
还未完全支持用户自定义数据类型,从 Flink 1.11 开始,仅可作为函数参数和返回值类型。