流转换成动态表

       当流中有新数据到来,初始的表中会插入一行;而基于这个表定义的 SQL 查询,就应该在之前的基础上更新结果。这样得到的表就会不断地动态变化,被称为"动态表"(Dynamic Tables)。动态表是Flink 在Table API 和SQL 中的核心概念,它为流数据处理提供了表和SQL 支持。我们所熟悉的表一般用来做批处理,面向的是固定的数据集,可以认为是"静态表";而动态表则完全不同,它里面的数据会随时间变化。

  动态表可以像静态的批处理表一样进行查询操作。由于数据在不断变化,因此基于它定义的 SQL 查询也不可能执行一次就得到最终结果。这样一来,我们对动态表的查询也就永远不会停止,一直在随着新数据的到来而继续执行。这样的查询就被称作"持续查询"(Continuous Query)。对动态表定义的查询操作,都是持续查询;而持续查询的结果也会是一个动态表。由于每次数据到来都会触发查询操作,因此可以认为一次查询面对的数据集,就是当前输入动态表中收到的所有数据。

  

持续查询的步骤如下:

  1. 流(stream)被转换为动态表(dynamic table);
  2. 对动态表进行持续查询(continuous query),生成新的动态表;
  3. 生成的动态表被转换成流。

   动态表是一个快照,每来一条数据进行查询一次,生成一个动态表(快照),连续不断的数据,变成了连续不断的快照,而连续不断的快照连起来这不就是结果流.

将流转换成动态表

  为了能够使用 SQL 来做流处理,我们必须先把流(stream)转换成动态表。如果把流看作一张表,那么流中每个数据的到来,都应该看作是对表的一次插入(Insert) 操作,会在表的末尾添加一行数据。因为流是连续不断的,而且之前的输出结果无法改变、只能在后面追加;所以我们其实是通过一个只有插入操作(insert-only)的更新日志(changelog) 流,来构建一个表。

public class TableToDataStreamForLog {

    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        DataStreamSource<Event> source = env.fromElements(
                new Event("Alice", "./home", 1000L),
                new Event("Alice", "./home", 1000L),
                new Event("Bob", "./cart", 1000L),
                new Event("Alice", "./prod?id=1", 5 * 1000L),
                new Event("Cary", "./home", 60 * 1000L),
                new Event("Bob", "./prod?id=3", 90 * 1000L),
                new Event("Alice", "./prod?id=7", 105 * 1000L)
        );

        StreamTableEnvironment tableEnvironment = StreamTableEnvironment.create(env);
        /**
         * 通过流,stream往上转换到table表结构层
         */
        Table table = tableEnvironment.fromDataStream(source);
        /**
         * 创建视图
         */
        tableEnvironment.createTemporaryView("eventTable", table);
        Table result = tableEnvironment.sqlQuery("select user,count(url) from eventTable group by user");
        tableEnvironment.toChangelogStream(result).print("sql->");

        env.execute("dataToStream");
    }
}

  用户在网站上的点击访问行为,数据类型被包装为 POJO 类型Event。我们将它转换成一个动态表,注册为EventTable。表中的字段定义如下:

[
user: VARCHAR,  // 用户名
url:    VARCHAR,    // 用户访问的 URL 
ts: BIGINT  // 时间戳
]

  当用户点击事件到来时,就对应着动态表中的一次插入(Insert)操作, 每条数据就是表中的一行;随着插入更多的点击事件,得到的动态表将不断增长。

  动态表记录了操作类型、数据类型、数据

 

posted on 2023-06-10 07:33  溪水静幽  阅读(64)  评论(0)    收藏  举报