写点什么

【FlinkSQL】Flink Table & SQL 数据类型

用户头像
Alex🐒
关注
发布于: 2021 年 06 月 10 日

主要引用官方文档 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

精度和小数位数固定的十进制数字的数据类型。

DECIMALDECIMAL(p)DECIMAL(p, s)
DECDEC(p)DEC(p, s)
NUMERICNUMERIC(p)NUMERIC(p, s)
复制代码

其中 p 是数字的位数(精度),s 是数字中小数点右边的位数(尾数)。p 的值必须介于 1 和 38 之间(含边界值)。s 的值必须介于 0 和 p 之间(含边界值)。其中 p 的缺省值是 10,s 的缺省值是 0。

NUMERICDEC 都等价于这个类型。

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。没有提供带有时区的时间。

TIMETIME(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


不支持和 BIGINT(JVM long 类型)互相转换,此类型是无时区的。


对于语义上更接近于 java.time.Instant 的需求请使用 TIMESTAMP WITH LOCAL TIME ZONE


TIMESTAMPTIMESTAMP(p)
TIMESTAMP WITHOUT TIME ZONETIMESTAMP(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 ZONETIMESTAMP(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 相比,时区偏移信息并非物理存储在每个数据中。相反,此类型在 Table 编程环境的 UTC 时区中采用 java.time.Instant 语义。每个数据都在当前会话中配置的本地时区中进行解释,以便用于计算和可视化。


此类型允许根据配置的会话时区来解释 UTC 时间戳,可以区分时区无关和时区相关的时间戳类型。

TIMESTAMP WITH LOCAL TIME ZONETIMESTAMP(p) WITH LOCAL TIME ZONE
TIMESTAMP_LTZTIMESTAMP_LTZ(p)
复制代码

其中 p 是秒的小数部分的位数(精度)。p 的值必须介于 0 和 9 之间(含边界值)。如果未指定精度,则 p 等于 6。

TIMESTAMP_LTZ 等价于此类型。

INTERVAL YEAR TO MONTH

一组由 Year-Month Interval 组成的数据类型,其范围从 -9999-11 到 +9999-11,可以表达:

  • 间隔年份、月份

INTERVAL YEARINTERVAL YEAR(p)INTERVAL YEAR(p) TO MONTHINTERVAL 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 DAYINTERVAL DAY(p1)INTERVAL DAY(p1) TO HOURINTERVAL DAY(p1) TO MINUTEINTERVAL DAY(p1) TO SECOND(p2)INTERVAL HOURINTERVAL HOUR TO MINUTEINTERVAL HOUR TO SECOND(p2)INTERVAL MINUTEINTERVAL MINUTE TO SECOND(p2)INTERVAL SECONDINTERVAL 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 标准相比,无法指定数组的最大长度,而是被固定为 2,147,483,647。另外,任何有效类型都可以作为子类型。

ARRAY<t>t ARRAY
复制代码

此类型用 ARRAY<t> 声明,其中 t 是所包含元素的数据类型。

t ARRAY 等价于 ARRAY<t> 类型。

MAP

将键(包括 NULL)映射到值(包括 NULL)的关联数组的数据类型。不能包含重复的键

元素类型没有限制;确保唯一性是用户的责任

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

(可能)具有 TRUEFALSEUNKNOWN 三值逻辑的布尔数据类型。

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 开始,仅可作为函数参数和返回值类型。

更多参考官方文档的说明。

发布于: 2021 年 06 月 10 日阅读数: 13
用户头像

Alex🐒

关注

还未添加个人签名 2020.04.30 加入

还未添加个人简介

评论

发布
暂无评论
【FlinkSQL】Flink Table & SQL 数据类型