flink 时态表 Join

注意: 时态表 时态变函数Blink都 支持推荐使用 但是时态表函数不支持DDL 标准SQL 创建所以 可以使时态表 功能相近 并且时态表可以DDL 创建 使用时态表函数 只能使用TABLE API 去注册

package com.cn.sql.joins.temporaljoins;

import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;

/**
 * 时态表 Join
 * 1 Syntax 语法
 * SELECT [column_list]
 * FROM table1 [AS ] --探针侧(普通表)
 * [LEFT] JOIN table2 FOR SYSTEM_TIME AS OF table1.{ proctime | rowtime } [AS ] --构建侧(版本表)
 * ON table1.column-name1 = table2.column-name1
 * 2 定义:
 * 基于事件时间的时态 Join
 * 基于事件时间的时态表 join 使用(左侧输入/探针侧) 的 事件时间 去关联(右侧输入/构建侧) 版本表 对应的版本。
 * 基于事件时间的时态表 join 仅支持关版本表或版本视图,版本表或版本视图只能是一个 changelog 流。
 * 但是,Flink 支持将 append-only 流转换成 changelog 流,因此版本表也可以来自一个 append-only 流。
 * 查看声明版本视图 获取更多的信息关于如何声明一张来自 append-only 流的版本表。
 * 将事件时间作为时间属性时,可将 过去 时间属性与时态表一起使用。这允许对两个表中在相同时间点的记录执行 Join 操作。
 * 与基于处理时间的时态 Join 相比,时态表不仅将构建侧记录的最新版本(是否最新由所定义的主键所决定)保存在 state 中,同时也会存储自上一个 watermarks 以来的所有版本(按时间区分)。
 * 例如,在探针侧表新插入一条事件时间时间为 12:30:00 的记录,它将和构建侧表时间点为 12:30:00 的版本根据时态表的概念进行 Join 运算。
 * 因此,新插入的记录仅与时间戳小于等于 12:30:00 的记录进行 Join 计算(由主键决定哪些时间点的数据将参与计算)。
 * 通过定义事件时间,watermarks 允许 Join 运算不断向前滚动,丢弃不再需要的构建侧快照。因为不再需要时间戳更低或相等的记录。
 * 3 注意
 * 注意 1: 基于事件时间的时态表 Join 是通过左右两侧的 watermark 触发,请确保为 join 两侧的表设置了合适的 watermark。
 * 注意 2: 基于事件时间的时态表 Join 的 join key 必须包含时态表的主键,例如:表 product_changelog 的主键 P.product_id 必须包含在 join 条件 O.product_id = P.product_id 中。
 * 注意3:  为了保证关联的信息的准确型推荐使用事件事件去定义版本表 防止数据错乱
 */
public class TemporalJoins {
    public static void main(String[] args) {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        StreamTableEnvironment Tenv = StreamTableEnvironment.create(env);
        /* 声明一张版本表 也叫构建测*/
        /*
         * 基于事件时间的时态表 join 仅支持关版本表或版本视图,版本表或版本视图只能是一个 changelog 流。
         * 我这里使用用CDC 也可以使用canal 输出到kafka但是必须是changelog 因为这样会有变更记录可查询
         * */
        Tenv.executeSql(
                "CREATE TABLE `Data_Input` (\n" +
                        "    id BIGINT,\n" +
                        "    actor VARCHAR(20),\n" +
                        "    alias VARCHAR(20),\n" +
                        "    order_time VARCHAR(20),\n" +
                        "    `ts` as   TO_TIMESTAMP(order_time),\n" +
                        "    WATERMARK FOR ts AS ts," +
                        "    PRIMARY KEY (`id`) NOT ENFORCED\n" +
                        ") WITH (\n" +
                        "    'connector' = 'mysql-cdc',  -- 可选 'mysql-cdc' 和 'postgres-cdc'\n" +
                        "    'hostname' = 'localhost',   -- 数据库的 IP\n" +
                        "    'port' = '3306',            -- 数据库的访问端口\n" +
                        "    'username' = 'root',        -- 数据库访问的用户名(需要提供 SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT, SELECT, RELOAD 权限)\n" +
                        "    'password' = 'root',        -- 数据库访问的密码\n" +
                        "    'database-name' = 'zhou',   -- 需要同步的数据库\n" +
                        "    'table-name' = 'mysqlcdc'       -- 需要同步的数据表名\n" +
                        ")");
        /*声明一张普通表 也叫 探针测 */
        Tenv.executeSql(
                "CREATE TABLE currency_rates (\n" +
                        "id BIGINT ,\n" +
                        "state STRING ,\n" +
                        " order_time TIMESTAMP(3),\n" +
                        " WATERMARK FOR order_time AS order_time  -- defines the necessary event time\n" +
                        ") \n" +
                        "WITH ( \n" +
                        "'connector'='kafka',\n" +
                        "'properties.bootstrap.servers'='localhost:9092' ,\n" +
                        "'properties.group.id'='test01',\n" +
                        "'topic'='kafkaSS',\n" +
                        "'format'='csv'" +
                        ")");
        /*声明一张 输出控制台表*/
        Tenv.executeSql(
                "CREATE TABLE print (\n" +
                        "id BIGINT,\n" +
                        "ts TIMESTAMP(3),\n" +
                        "actor VARCHAR(20),\n" +
                        "alias VARCHAR(20)," +
                        "state STRING,\n" +
                        "order_time TIMESTAMP(3),\n" +
                        "PRIMARY KEY (`id`) NOT ENFORCED" +
                        ")\n " +
                        "WITH (\n" +
                        "'connector'='print'" +
                        ")\n");
        //Tenv.executeSql("INSERT INTO  print SELECT id,actor,alias,order_time FROM Data_Input");
        /*查询语句 版本表关联 普通表 */
        Tenv.executeSql("INSERT INTO print SELECT \n" +
                "  O.id,\n" +
                "   ts,\n" +
                "  actor,\n" +
                "  alias,\n" +
                "  state,\n" +
                "O.order_time\n" +
                "FROM currency_rates AS O\n" +
                "LEFT JOIN Data_Input FOR SYSTEM_TIME AS OF O.order_time AS P\n" +
                "ON O.id = P.id");
    }
}

你可能感兴趣的:(flink,flink,big,data,大数据)