flink sql设置表的时间属性

293 阅读2分钟

一、事件时间属性

1. 在创建表的DDL语句中定义

 CREATE TABLE EventTable(
     user STRING,
     url STRING,
     ts TIMESTAMP(3),    --  TIMESTAMP(3)指定小数秒的精度
     WATERMARK FOR ts AS ts - INTERVAL '5' SECOND  -- 指定事件时间字段,且设置watermark
 ) WITH (
 ...
 );

Flinksql 中支持的事件时间属性数据类型必须为 TIMESTAMP 或者 TIMESTAMP_LTZ。这里 TIMESTAMP_LTZ 是指带有本地时区信息的时间戳( TIMESTAMP WITH LOCAL TIME ZONE);一般情况下如果数据中的时间戳是“年-月-日-时-分-秒”的形式,那就是不带时区信息的,可以将事件时间属性定义为 TIMESTAMP 类型。

而如果原始的时间戳就是一个长整型的毫秒数,这时就需要另外定义一个字段来表示事件时间属性,类型定义为 TIMESTAMP_LTZ 会更方便。

CREATE TABLE events (  
    user STRING,  
    url STRING,  
    ts BIGINT,  
    ts_ltz AS TO_TIMESTAMP_LTZ(ts, 3), -- 将长整形毫秒数转换成TIMESTAMP_LTZ,作为新字段
    WATERMARK FOR ts_ltz AS ts_ltz - INTERVAL '5' SECOND  
) WITH (  
...  
);

这里我们另外定义了一个字段 ts_ltz,是把长整型的 ts 转换为 TIMESTAMP_LTZ 得到的;进而使用 WATERMARK 语句将它设为事件时间属性,并设置 5 秒的水位线延迟。

2. 在数据流转换为表时定义

1) 在流中已经设置好了事件时间和水位线

注:watermark是在流中就已经指定了,需要指定的是在sql中的事件时间。

 // 方法一:
 // 流中数据类型为二元组 Tuple2, 包含两个字段;需要自定义提取时间戳并生成水位线
 DataStream<Tuple2<String, String>> stream =inputStream.assignTimestampsAndWatermarks(...);
 
 // 声明一个额外的逻辑字段作为事件时间属性
 // $("ts").rowtime()表示将流中的事件时间提取出来,作为新的一列,指定为sql中的数据的事件时间
 Table table = tEnv.fromDataStream(stream, $("user"), $("url"),$("ts").rowtime());

2) 流中的元素为三元组,包含一个时间字段,在流转table中,将该字段作为事件时间字段。

 // 方法二:
 // 流中数据类型为三元组 Tuple3,最后一个字段就是事件时间戳
 DataStream<Tuple3<String, String, Long>> stream =inputStream.assignTimestampsAndWatermarks(...);
 // 不再声明额外字段,直接用最后一个字段作为事件时间属性
 Table table = tEnv.fromDataStream(stream, $("user"), $("url"),$("ts").rowtime());

二、 事件时间属性

1. 在创建表的DDL语句中定义

用一个 AS 语句来在表中产生数据中不存在的列,并且可以利用原有的列、各种运算符及内置函数。

CREATE TABLE EventTable(  
    user STRING,  
    url STRING,  
    ts AS PROCTIME()  -- 内置的 PROCTIME()函数来指定当前的处理时间属性,返回的类型是 TIMESTAMP_LTZ
) WITH (  
...  
);

2. 在数据流转换为表时定义

处理时间属性同样可以在将DataStream转换为表的时候来定义。我们调用fromDataStream()方法创建表时,可以用.proctime()后缀来指定处理时间属性字段。由于处理时间是系统时间,原始数据中并没有这个字段,所以处理时间属性一定不能定义在一个已有字段上,只能定义在表结构所有字段的最后,作为额外的逻辑字段出现。

代码中定义处理时间属性的方法如下:


DataStream<Tuple2<String, String>> stream = ...;  

// 声明一个额外的字段作为处理时间属性字段  
Table table = tEnv.fromDataStream(stream, $("user"), $("url"),$("ts").proctime());