Flink SQL之时态表(Temporal Tables)

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
简介: 笔记

目录


时态表(Temporal Table)是一张随时间变化的表 – 在 Flink 中称为动态表,时态表中的每条记录都关联了一个或多个时间段,所有的 Flink 表都是时态的(动态的)。

时态表包含表的一个或多个有版本的表快照,时态表可以是一张跟踪所有变更记录的表(例如数据库表的 changelog,包含多个表快照),也可以是物化所有变更之后的表(例如数据库表,只有最新表快照)。


版本: 时态表可以划分成一系列带版本的表快照集合,表快照中的版本代表了快照中所有记录的有效区间,有效区间的开始时间和结束时间可以通过用户指定,根据时态表是否可以追踪自身的历史版本与否,时态表可以分为 版本表 和 普通表。


版本表: 如果时态表中的记录可以追踪和并访问它的历史版本,这种表我们称之为版本表,来自数据库的 changelog 可以定义成版本表。


普通表: 如果时态表中的记录仅仅可以追踪并和它的最新版本,这种表我们称之为普通表,来自数据库 或 HBase 的表可以定义成普通表。


注意 仅 Blink planner 支持此功能。

10.png11.png12.png13.png

如果流延迟过来的数据要跟之前的维表数据做关联,即根据流的事件时间,查找某个时间点的维度数据而不是当前维度表数据。


比如这样一个场景:用户的订单表和和商品维度表,将维度表设置成时态表,这样用户就可以根据订单表中的下单时间Join下单时的商品当时最新的维度数据


Flink引入了temporal table, Temporal Table是Append Only表(只允许插入记录,而不会修改、删除记录)上的物化视图,它把Append Only的表变化解释为表的Changelog,并提供特定时间版本的表数据、将每个时间点映射到静态关系中,表的版本数据存储在状态里。在Flink中,通过TemporalTableFunction实现对temporal table的访问,必须定义主键和时间戳属性,主键确定覆盖哪些行,时间戳确定有效的时间,也就是表的数据版本。


时态表代码开发:

数据源:ratesHistory.csv

RMB,114,2015-01-01 00:00:00
RMB,115,2015-01-03 00:00:00
RMB,116,2015-01-19 00:00:00
Euro,119,2015-01-03 00:00:00
USD,99,2015-01-03 00:00:00
USD,100,2015-01-03 00:00:00
Euro,118,2015-01-03 00:00:00

数据源:rateOrder.csv

1,29,RMB,2015-01-02 00:00:00
2,19,RMB,2015-01-03 00:00:00
3,33,RMB,2015-01-11 00:00:00
4,55,RMB,2015-01-21 00:00:00
package com.aikfk.flink.sql;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;
import org.apache.flink.types.Row;
/**
 * @author :caizhengjie
 * @description:TODO
 * @date :2021/4/5 10:32 下午
 */
public class TemporalTableJoinEventTime {
    public static void main(String[] args) throws Exception {
        // 1.准备环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        // 2.创建TableEnvironment(Blink planner)
        EnvironmentSettings settings = EnvironmentSettings.newInstance().inStreamingMode().useBlinkPlanner().build();
        StreamTableEnvironment tableEnvironment = StreamTableEnvironment.create(env , settings);
        // 3.文件path
        String ratesHistoryPath = "/Users/caizhengjie/IdeaProjects/aikfk_flink/src/main/java/resources/ratesHistory.csv";
        String ratesOrderPath = "/Users/caizhengjie/IdeaProjects/aikfk_flink/src/main/java/resources/rateOrder.csv";
        // 4.DDL
        String ratesHistory_ddl =
                "create table currency_rates (\n" +
                        " currency STRING,\n" +
                        " conversion_rate DECIMAL(32, 2),\n" +
                        " update_time TIMESTAMP(3),\n" +
                        " PRIMARY KEY (currency) NOT ENFORCED,\n" +
                        " WATERMARK FOR update_time AS update_time \n" +
                        ") WITH (\n" +
                        " 'connector.type' = 'filesystem',\n" +
                        " 'connector.path' = '"+ratesHistoryPath+"',\n" +
                        " 'format.type' = 'csv'\n" +
                        ")";
        tableEnvironment.executeSql(ratesHistory_ddl);
        String ratesOrder_DDL =
                "create table orders (\n" +
                        " order_id    STRING,\n" +
                        " price       DECIMAL(32,2),\n" +
                        " currency    STRING,\n" +
                        " order_time  TIMESTAMP(3),\n" +
                        " WATERMARK FOR order_time AS order_time \n" +
                        ") WITH (\n" +
                        " 'connector.type' = 'filesystem',\n" +
                        " 'connector.path' = '"+ratesOrderPath+"',\n" +
                        " 'format.type' = 'csv'\n" +
                        ")";
        tableEnvironment.executeSql(ratesOrder_DDL);
        // 6.通过SQL对表的查询,生成结果表
        String sql =
                "SELECT \n" +
                        "     order_id,\n" +
                        "     price,\n" +
                        "     orders.currency,\n" +
                        "     conversion_rate,\n" +
                        "     order_time\n" +
                        " FROM orders\n" +
                        " LEFT JOIN currency_rates FOR SYSTEM_TIME AS OF orders.order_time\n" +
                        " ON orders.currency = currency_rates.currency";
        Table table = tableEnvironment.sqlQuery(sql);
        // 7.将table表转换为DataStream
        DataStream<Tuple2<Boolean, Row>> retractStream = tableEnvironment.toRetractStream(table, Row.class);
        retractStream.print();
        env.execute();
        /**
         * 2> (true,1,29.00,RMB,114.00,2015-01-02T00:00)
         * 2> (true,4,55.00,RMB,116.00,2015-01-21T00:00)
         * 2> (true,2,19.00,RMB,115.00,2015-01-03T00:00)
         * 2> (true,3,33.00,RMB,115.00,2015-01-11T00:00)
         */
    }
}



相关实践学习
基于Hologres轻松玩转一站式实时仓库
本场景介绍如何利用阿里云MaxCompute、实时计算Flink和交互式分析服务Hologres开发离线、实时数据融合分析的数据大屏应用。
Linux入门到精通
本套课程是从入门开始的Linux学习课程,适合初学者阅读。由浅入深案例丰富,通俗易懂。主要涉及基础的系统操作以及工作中常用的各种服务软件的应用、部署和优化。即使是零基础的学员,只要能够坚持把所有章节都学完,也一定会受益匪浅。
相关文章
|
3月前
|
SQL 存储 API
Flink实践:通过Flink SQL进行SFTP文件的读写操作
虽然 Apache Flink 与 SFTP 之间的直接交互存在一定的限制,但通过一些创造性的方法和技术,我们仍然可以有效地实现对 SFTP 文件的读写操作。这既展现了 Flink 在处理复杂数据场景中的强大能力,也体现了软件工程中常见的问题解决思路——即通过现有工具和一定的间接方法来克服技术障碍。通过这种方式,Flink SQL 成为了处理各种数据源,包括 SFTP 文件,在内的强大工具。
184 15
|
2月前
|
SQL 大数据 API
大数据-132 - Flink SQL 基本介绍 与 HelloWorld案例
大数据-132 - Flink SQL 基本介绍 与 HelloWorld案例
49 0
|
3月前
|
SQL 安全 数据处理
揭秘数据脱敏神器:Flink SQL的神秘力量,守护你的数据宝藏!
【9月更文挑战第7天】在大数据时代,数据管理和处理尤为重要,尤其在保障数据安全与隐私方面。本文探讨如何利用Flink SQL实现数据脱敏,为实时数据处理提供有效的隐私保护方案。数据脱敏涉及在处理、存储或传输前对敏感数据进行加密、遮蔽或替换,以遵守数据保护法规(如GDPR)。Flink SQL通过内置函数和表达式支持这一过程。
87 2
|
3月前
|
SQL 大数据 数据处理
奇迹降临!解锁 Flink SQL 简单高效的终极秘籍,开启数据处理的传奇之旅!
【9月更文挑战第7天】在大数据处理领域,Flink SQL 因其强大功能与简洁语法成为开发者首选。本文分享了编写高效 Flink SQL 的实用技巧:理解数据特征及业务需求;灵活运用窗口函数(如 TUMBLE 和 HOP);优化连接操作,优先采用等值连接;合理选择数据类型以减少计算资源消耗。结合实际案例(如实时电商数据分析),并通过定期性能测试与调优,助力开发者在大数据处理中更得心应手,挖掘更多价值信息。
48 1
|
3月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
5月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
125 13
|
5月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
5月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
66 6
|
5月前
|
存储 SQL C++
对比 SQL Server中的VARCHAR(max) 与VARCHAR(n) 数据类型
【7月更文挑战7天】SQL Server 中的 VARCHAR(max) vs VARCHAR(n): - VARCHAR(n) 存储最多 n 个字符(1-8000),适合短文本。 - VARCHAR(max) 可存储约 21 亿个字符,适合大量文本。 - VARCHAR(n) 在处理小数据时性能更好,空间固定。 - VARCHAR(max) 对于大文本更合适,但可能影响性能。 - 选择取决于数据长度预期和业务需求。
431 1
|
5月前
|
SQL Oracle 关系型数据库
MySQL、SQL Server和Oracle数据库安装部署教程
数据库的安装部署教程因不同的数据库管理系统(DBMS)而异,以下将以MySQL、SQL Server和Oracle为例,分别概述其安装部署的基本步骤。请注意,由于软件版本和操作系统的不同,具体步骤可能会有所变化。
353 3