00:00
刚才我们介绍的是在创建一张表的时候啊,Create table这样一个DDL里边直接去指定当前的时间属性字段啊,在实际应用的过程当中,这种方式可能是比较常见的啊,因为我们说它就相当于我们可以直接使用熟悉的CQ去做所有的流处理操作了,跟前面我们所说的data stream就完全没有关系了。那我们会想到啊,假如说我还是觉得之前那个data stream比较好用,我能不能直接像之前我们在做这个快速上手的时候那样啊,先去得到一个data stream,然后再把它转换成一张表啊,那接下来然后再去指定时间属性字段,然后再去进行窗口操作,能不能这样做呢?诶,当然也是可以的,比如说我们可以把之前这个啊也是copy过来。前面的这个测试。我们把它叫做第一种情况。在。创建表的DDL中指定。
01:01
时间属性字段。那接下来就还有第二种方式。第二种方式是在将流转换成表的时候,指定时间属性字段。哎,那这两种方式其实就对应着我们啊不同的创建表的方式了,哎,就其实都是在创建表的时候就可以直接指定当前的时间主义字段,因为我们知道它是加了一个字段上去,当然就是跟表创建有关了,所以接下来呢,我们就把之前。做过的啊,这些把data stream转换成表的这些方式啊,直接都copy过来,当然了,因为这个里边我们涉及到了data stream的转换操作啊,所以这里边我们应该把下划线这里引入啊,另外呢,这个表环境就不要创建两次了。只创建一个table env就可以了,现在我们做的操作就是基于流式的执行环境,先去from element读取一个数据流,得到一个stream,这是一个data stream,接下来呢?呃,调用表环境的from data方法,把data stream转换成一个even table转换成一个table,然后接下来我们可以考虑把这个table even the table也做一个打印print game,看看它里边的字段到底是什么,如果前面我们没有指定时间属性字段的话,那自然想到了这个,得到的啊,肯定就是。
02:26
跟even的这个样例类里边定义的三个字段是完全一样的,哎,我们看到就是user URL time step time的类型是begin,然后接下来呢,如果说我们想要对于时间进行处理啊,想要做这个时间窗口的操作,那就必须指定时间属性字段,那这种定义方式呢,其实它是在前面这个数据流里边。就要先去提取时间戳,然后生成watermark,先做这步操作,那么后边呢,把流转换成表的时候就简单多了,后边就单独的去做一个声明就可以了,我们看看这个方式怎么做啊,呃,前面我们知道就需要做一个哦,那我们如果是直接升序数据的话,可以直接assign asending time stamps,如果是更一般化的乱序数据的话,哎,那就是assign time stamps and watermarks,那这里边。
03:17
我们知道要传入的是一个wal strategy。哎,那这里我们可以直接使用一个比方说for bonded out of order Miss这样的一个方法。里边呢,只要给一个max out of order这样一个Du啊,一个最大乱序程度就可以了。所以这里边我们一般给一个duration啊,Of seconds,给一个几秒钟两秒钟的一个延迟时间,哎,这样的话就定义了生成水位线的策略,那当然了,这个没完,因为我们说这个本身o rock strategy啊,在这里这个延迟时间是生成水位线用的,那到底基于哪个字段啊,基于哪一个属性去提取时间戳呢?这个我们还还没定义啊,诶,所以这个是需要在后边单独的定义一个with time step aign。
04:08
里边我们可以直接拗一个reliable。Time stamp。End啊,然后这里边需要有一个泛型类型啊,我们现在当然就是event类型啊,就是这样的一个实践类型,里边必须要实现的方法是一个extract time step啊,这里边我们基于当前的事件T,那么想要获取的就是它的time step,就是它的时间戳二啊,那在这个流string去指定当前的时间属性的时候呢,要的就是一个长整型的以毫秒为单位的时间戳,这个就跟CQ里边不太一样啊,CQ里面我们要的必须是一个time stamp类型啊,那现在的话这个就完全没有问题了。在data streamam当中,如果我们已经指定了怎么样提取时间戳,然后生成水位线啊,那接下来呢,转换成表的时候,自然就可以直接的确定我们当前时间属性是什么,就不需要像之前这样啊,单独去定义这个water mark怎么样去生成了,那但是呢,这里边我们必须还得去单独生成一个时间属性字段,因为在这个表里边时间属性字段是单独的一个字段嘛,诶之前我们看到是多了一个ET这样一个字段,所以接下来我们其实是需要在调用from data streamam的这个方法的时候,不能直接就用样例类里边所有的字段名称转换过来就完了,因为我们还要追加,所以呢,接下来我们应该是在后边增加一些参数,那就是所谓的expression,表示指定当前转换生成的表当中的每一个列属性字段到底是什么?
05:40
啊,那所以这个的话,我们就可以直接do。啊,那需要把这个Dollar做一个引入啊,引入flink table API expressions下边的这个Dollar符一个表达式,那首先第一个比方说我们也可以换一下这个顺序啊,第一个我们不要这个user了,我要URL。然后第二个。
06:00
第二个是user,如果说我们不想要这个user这个名称的话,也可以把它做一个重命名,As。UID。啊,然后后边我们可以继续。Time。注意这个名称必须还得是之前样例类里边对应的那个字段名称啊,如果说我们不想要这个名字的话,在表里边可以做一个S,然后做一个重命名啊,这个是完全可以的啊,那比方说我们在这儿asts,因为我们说在CQ里边啊,他们Sam是关键字嘛,所以一般情况我们不要跟它重名好,那有了这些之后,接下来的问题就在于,那我们多出来的那个时间属性字段怎么办呢?啊,那这里我们可以换一行看的清楚一点啊那。在这里我们就直接后边。可以追加一个字段,比方说就叫做ET。哎,那我们想在这个样力类里边并没有ET这样一个名称啊,没有这样一个属性啊,那怎么办呢,后边只要加一个。我看调一个方法叫做柔态,我们还记得之前打印出来这个ET,它的后面有一个什么特征吗?加了一个星号,指定它是柔态,这就表示这是当前的时间属性字段,所以如果说我们是这样一个Dollar ET,然后点周time的话,就相当于这是我们单独追加的一个字段,一个列,那这个列呢,就是基于之前我们data stream里边已经指定好的那个时间戳,指定出来的一个时间属性字段。
07:24
啊,那对应的那个水位线生成策略,当然也是根据之前指定好的了啊,所以这里面我们只要加一个点周T就可以。接下来我们再来运行一下,看一看现在even table它的表结构又是什么样?哎,我们看到现在它就多了一个ET,它的类型是time STEM,这就是我们说的啊时间属性,它的类型必须是time STEM,或者是time STEM l TC,后面加上它是RO time。当然了,这里就没有单独的再去强调这个water mark是什么样的啊,因为water mark啊,那相当于已经是在我们之前这个数据流里面,Data stream里边已经指定生成了,所以这里边我们的表表的字段里面就不用去单独定义了。
08:05
这就是另外一种方式啊,就是在把流转换成表的时候,去指定时间属性。那这里要说的还有另外一种比较特殊的方法,就是有时候我们可能看到这种用法啊,就是本身这个字段里面不是有一个time STEM吗?不是有一个TS吗?那我何必还要再加一个ET呢?我们会发现啊,在这张表里边,它们最大的区别就是就是类型不一样,就这个是big in,那下面这个是time STEM。如果我觉得之后在这个表里边长整形的这个TS已经没用了的话,那其实我可以做另外一个操作。我直接把这个先注掉,然后复制一份,我们看一看它可以写成什么样子呢。换行换下来啊,那这里我们就可以直接不要再去单独声明一个ET字段了,我们就直接基于原始有的这个time STEM就可以了啊就怎么样呢,直接后边掉一个点肉态。这样的话,就相当于把原始的time STEM这样一个属性定义成了当前的时间属性字段,当然了,它的类型也就不再会是之前的big in了,而是直接转换成了TIME3。
09:13
啊,那当然了,我们如果觉得这个time还是名字不太好的话,还想做一个重命名,那就调用了real time之后再去做一个as转换,把它重命名叫做TS就可以了。接下来我们再来重新运行一下,看一看当前这个表结构变成了什么样子,我们看,诶,现在这就只有一个TS,它的类型呢,是TIME33。它是当前的时间属性字段,事件时间余下的时间属性字段。这就是我们定义时间属性字段的第二种方法,在把一个data stream转换成表的时候去指定时间属性。如果我们对于数据流data的操作更加熟悉的话啊,那用这种方式看起来也比较简单啊,那当然了,因为data stream本身是不支持带时区的时间出信息的啊,啊,就是像这个他们散LTZ这样的类型本身在这个data stream里边是没有的啊,所以如果用这种方式转换的话,得到的就只能是time Sam类型的时间属性字段,而不会得到time Sam l TZ类型。
10:19
这就是关于定义时间属性的两种方法。
我来说两句