【flink】 各种join类型对比
表定义
-
动态表(dynamic table):动态表是流的另一种表达方式,动态表作为一个逻辑的抽象概念,使我们更容易理解flink中将streaming发展到table这个层次的设计,本质都是对无边界、持续变更数据的表示形式,所以动态表与流之间可以相互转换。
-
版本表(dynamic table):动态表之上的定义,版本是一个拥有主键和时间属性的动态表(建表语句必需包含PRIMARY KEY和WATERMARK),所以版本表可以追踪每个key在某时间点/时间内的变化情况。版本表可以直接从changelog格式的source创建,或者基于append-only的源创建版本视图。
-
时态表(temporal table):时态表是随着时间变化而变化的,也就是动态表,时态表包含一个或多个版本表的快照;当它能追踪所有记录的历史变更(来自数据库的changelog)时,就是个版本表;如果它只能表示所有记录经过物化后的最新快照(直接一个数据库表),那就是个普通表。
Regular Joins
Regular Joins是flink这么多join类型中最普通的,任意一侧的数据流有变更或者新增,都会影响到join结果。Regular joins是通过把双流的输入数据都保存在flink的状态中,存在state过度膨胀的隐患,所以我们在使用时要合理设置table状态的TTL(table.exec.state.ttl),这要结合具体的业务场景,否则会影响join结果的正确性。
有两种join类型,内连接(INNER Equi-JOIN)和外连接(OUTER Equi-JOIN),两者都只支持等值连接,且至少一个连接条件。
Interval Joins
Interval join要求至少有一个等值谓词连接和一个时间约束条件,这个时间属性定义了流的时间范围,且作为WATERMARK
ltime = rtime
ltime >= rtime AND ltime < rtime + INTERVAL ‘10’ MINUTE
ltime BETWEEN rtime - INTERVAL ‘10’ SECOND AND rtime + INTERVAL ‘5’ SECOND
- 与Regular join一样是双流,但是它加上了时间区间的概念,可以清理状态中较旧的数据,而不会影响join结果的正确性
- 通过InnerJoin算子实现,水位线来控制join的数据区间以及清理数据,所以两个输入流都要定义WATERMARK,否则会变回Regular join
- WATERMARK可以定义为event-time或process-time
- 只支持append-only的输入流,当尝试使用cdc作为输入源(Retract)时出报错
Exception in thread "main" org.apache.flink.table.api.TableException: StreamPhysicalIntervalJoin doesn't support consuming update and delete changes which is produced by node TableSourceScan(table=[[ tb_order]], fields=[order_id, price, currency, order_time])
Temporal Joins
与时态表的join,通过上述时态表的描述可得知,可以关联得到记录的历史版本或只能得到最新版本,flink sql遵循SQL:2011的标准语法
SELECT [column_list]FROM table1 [AS <alias1>][LEFT] JOIN table2 FOR SYSTEM_TIME AS OF table1.{ proctime | rowtime } [AS <alias2>]ON table1.column-name1 = table2.column-name1
从使用形式划分,可以分为3种:Event Time Temporal Join、Processing Time Temporal Join、Temporal Table Function Join
Event Time Temporal Join
Event Time temporal join的是一个版本表,意味着可以根据主表的事件时间关联到当时维表的具体版本。
Temporal table join currently only supports ‘FOR SYSTEM_TIME AS OF’ left table’s time attribute field
Event-Time Temporal Table Join requires both primary key and row time attribute in versioned table, but no row time attribute can be found.
Temporal table’s primary key [currency] must be included in the equivalence condition of temporal join
- 左表必需定义事件时间,右表除了定义事件时间外,还需要定义主键(即版本表)
- 水位线替触发join,所以两侧流都需要设置正常的水位线
- 右表的主键必需作为等值谓词连接
- 与regular join相比,结果不会受到右侧流影响,即输出结果以左流为主,右流只是补充了左流的信息,效果与left join相似
- 与interval join相比,不需要定义时间窗口,即可以关联到更久之前的维度,因为版本表会保存全量维度最新版本以及上一个水位线之后的变更
- 一个水位线之前的版本数据将会被清理,因为随着水位线的推移,这些数据将不会再被用到
Processing Time Temporal Join
Processing-time temporal join is not supported yet
从flink 1.14开始已经不再支持这种方式,可以使用temporal table function语法替换
右表定义process-time属性,总是能关联到最新的右表记录,其实这和lookup join差不多,只不过右表的记录是以HashMap全部保存着最新的版本在状态中。这种方式的强大之处在于,可以直接对接不能变成flink动态表的外部表(例如hbase)
- 与regular joins相比,右表的数据变化不会影响到之前已经join出的结果
- 与interval joins相比,不需要定义时间窗口,且所有旧版本数据都不会保存在状态中
Temporal Table Function Join
Join key must be the same as temporal table’s primary key
create table if not exists tb_order (`order_id` int,`price` int,`currency` string,`order_time` timestamp(3),`proc_time` AS PROCTIME(),primary key(order_id) not enforced)WITH ('connector'='mysql-cdc','table-name'='tb_order',)create table if not exists tb_currency (`currency` string,`rate` int,`update_time` timestamp(3),`proc_time` AS PROCTIME(),)WITH ('connector'='mysql-cdc','table-name'='tb_currency',)TemporalTableFunction rate = tEnv.from("tb_currency").createTemporalTableFunction("proc_time", "currency");tEnv.createTemporarySystemFunction("rate",rate);select * from tb_order o , LATERAL TABLE(rate(o.order_time)) c where o.currency=c.currency
上面例子实现了process time temporal join,两建表语句都不指定事件时间,且tb_currency无需指定primary key(即非版本表),但是在定义TemporalTableFunction可以指定任意字段为主键,所以如果建表语句指定了事件时间,且TemporalTableFunction也使用事件时间,那么相当于间接创建了版本表。
- 先要定义table funtion,指定一个时间属性(event-time或process-time)和主键
- TemporalTableFunction定义的主键必须作为等值谓词连接
- 除了可以和版本表join,还能和普通的表示最新版本的表/视图join,即它包含了event-time/processing-time temporal join两种
Lookup Join
通过查询外部存储系统的数据以丰富流的属性,这种join方式要求流表必须有一个processing time属性,外部数据表的connector要实现LookupTableSource
接口
CREATE TEMPORARY TABLE Customers (id INT,name STRING,country STRING,zip STRING) WITH ('connector' = 'jdbc','table-name' = 'customers');SELECT o.order_id, o.total, c.country, c.zipFROM Orders AS oJOIN Customers FOR SYSTEM_TIME AS OF o.proc_time AS cON o.customer_id = c.id;
- 外部表的数据变化不会影响到已经join出的结果
- 上面所有join都是双流,而lookup join是单流
相关文章:

【flink】 各种join类型对比
表定义 动态表(dynamic table):动态表是流的另一种表达方式,动态表作为一个逻辑的抽象概念,使我们更容易理解flink中将streaming发展到table这个层次的设计,本质都是对无边界、持续变更数据的表示形式,所以动态表与流之…...

常用正则表达式
一、校验数字的表达式 数字:^[0-9]*$ n位的数字:^\d{n}$ 至少n位的数字:^\d{n,}$ m-n位的数字:^\d{m,n}$ 零和非零开头的数字:^(0|[1-9][0-9]*)$ 非零开头的最多带两位小数的数字:^([1-9][0-9]*)(.[0…...

PMP考试有没有什么技巧可以介绍一下么?
一、试题形式 ——中英文对照 即每道题都是一遍英文,一遍翻译的中文,在审题的时候有一些小的技巧需要注意。首先如果你的英文水平足够好,建议直接阅读原文。PMP试题毕竟是美国人出的,语言的组织、思想的表达,肯定更符…...

2022-2023年营销报告(B站平台) | 5大行业势态、流量大盘全景洞察
一直以来,手持高活跃、高粘性用户群体的B站是行业用来观察年轻人消费习惯的重要平台。以至于用户群体的不断壮大带动了B站的商业价值。如今B站的商业舞台越来越大,不断地向外界招手,欢迎更多品牌积极加入到这个千万年轻人聚集的内容社区。为了…...

Python的异常与工具包
异常 当检测到一个错误时,python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的异常。 捕获异常 世界上没有完美的程序,任何程序在运行的过程中,都有可能出现异常,导致程序无法完美运行…...

基于SSM的婴幼儿商城
基于SSM的婴幼儿商城 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背景介绍: …...

2023年新能源汽车行业研究报告
第一章 行业概况 新能源汽车,是指采用新型动力系统,完全或者主要依靠新型能源驱动的汽车,包括纯电动汽车、插电式混合动力汽车、增程式混合动力汽车和燃料电池汽车等。国际上,混合动力汽车(含中混、强混、插电式混动&…...

手写Promise方法(直击Promise A+规范)
前言:大家好,我是前端獭子。高效优雅是我的创作方式。学习是一个渐进的过程,要把知识串联起来才能解决某一方面的问题。 Promise 构造函数 我们先来写 Promise 构造函数的属性和值,以及处理new Promise()时会传入的两个回调函数。…...

GooglePlay SSL Error Handler
应用上架GooglePlay 收到邮件提示 出现这个原因是因为我在app中使用webview加载Https的H5界面,在onReceivedSslError()中处理SslErrorHandler时,出现白屏现象,原因是webview默认在加载有证书验证的url时,会默认使用handler.cancel…...

OpenStack手动分布式部署Keystone【Queens版】
目录 Keystone简介 1、登录数据库配置(在controller执行) 1.1登录数据库 1.2数据库里创建keystone 1.3授权对keystone数据库的正确访问 1.4退出数据库 2、数据库导入Keystone表(在controller执行) 2.1安装httpd mod_wsgi 2.2备…...

AAPT2
概念 AAPT2(Android 资源打包工具)是一种构建工具,Android Studio 和 Android Gradle 插件使用它来编译和打包应用的资源。AAPT2 会解析资源、为资源编制索引,并将资源编译为针对 Android 平台进行过优化的二进制格式。 Android Gradle 插件 3.0.0 及更高版本在默认情况下…...

kafka学习
概念: broker: 1台服务器的kafka进程,它是kafka的工作者。类似Hbase的regionServer,hdfs的Datanodetopic: 订阅发布模式的kafka中有消息主题producer:生产者customer:消费者 基础架构: 元数据:…...

坐拥两条黄金赛道,爱博医疗未来必是星辰大海!
尽管2022年疫情反复,但爱博医疗仍交出了亮眼的“答卷”。图源:爱博医疗2023年2月14日晚间,爱博医疗披露了2022年度业绩快报,营收5.79亿元,同比增长33.81%;归母净利润2.32亿元,同比增长35.27%&am…...

DEV C++的使用入门程序做算术运算
DEV C Dev-C (有时候也称为 Dev-Cpp)是一个免费软件,最早是由 BloodShed 公司开发的,在版本 4.9.2 之后该公司停止开发并开放源代码。然后由 Orwell 接手进行维护,陆续开发了几个版本,后来也有其他开发人员…...

华为OD机试真题Python实现【商人买卖】真题+解题思路+代码(20222023)
商人买卖 题目 商人经营一家店铺,有number种商品, 由于仓库限制每件商品的最大持有数量是item[index] 每种商品的价格是item-price[item_index][day] 通过对商品的买进和卖出获取利润 请给出商人在days天内能获取的最大的利润 注:同一件商品可以反复买进和卖出 🔥🔥�…...

随想录二刷(数组二分法)leetcode 704 35 34 69 367
第一题 leetcode 704.二分查找 二分法的思路 二分法的思路很简单 数组必须有序先查找中间元素进行比较得出大小再考虑向左比较还是向右比较 代码实现 class Solution { public:int search(vector<int>& nums, int target) {int left 0;int right nums.size() -…...

【微信小程序】--WXML WXSS JS 逻辑交互介绍(四)
💌 所属专栏:【微信小程序开发教程】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &#…...

c/c++开发,无可避免的模板编程实践(篇八)
一、借用标准库模板构造自己的模板 通常,模板设计是遵循当对象的类型不影响类中函数的行为时就使用模板。这也就是为何标准库提供大部分的模板都是与容器、迭代器、适配器、通用算法等有关,因为这些主要是除了对象集合行为,如读写、增删、遍历…...

Leetcode13. 罗马数字转整数
一、题目描述: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符数字I1V5X10L50C100D500M1000 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII &…...

元宇宙对营销方式的影响
营销方式的变化通常伴随着技术的发展。我们已经看到营销方式从印刷媒体、电视、广播到互联网的转变。而现在,我们又处在下一个营销方式大跃进的风口浪尖上。关于元宇宙及其潜在的变革性影响,人们已经讨论了很多。虽然与元宇宙相关的大多数东西在很大程度…...

PERCCLI命令行程序说明
Dell EMC PowerEdge RAID控制器(PERC)命令行界面(CLI)实用程序用于管理RAID卡相关的配置和信息,命令的子命令和选项如下所示: help - lists all the commands with their usage. E.g. perccli help <command> help - gives details about a parti…...

系统架构——分布式架构负载均衡系统设计实战
摘要 关于“负载均衡”的解释,百度词条里:负载均衡,英文叫Load Balance,意思就是将请求或者数据分摊到多个操作单元上进行执行,共同完成工作任务。负载均衡(Load Balance)建立在现有网络结构之…...

机器学习算法: AdaBoost 详解
1. 集成学习概述 1.1. 定义 集成学习(Ensemble learning)就是将若干个弱分类器通过一定的策略组合之后产生一个强分类器。 弱分类器(Weak Classifier)指的就是那些分类准确率只比随机猜测略好一点的分类器,而强分类器&…...

6.824lab1总结
目录总体概要核心结构体coordinator思路:任务池管理RPC函数worker思路:实现细节总体概要 程序主要由mrcoordinator.go、mrworker.go为启动模块。 mrcoordinator.go: 启动rpc服务,循环等待m.Done()为true时退出。mrwoker.go:调用mr.worker(mapf, reduce…...

NIO蔚来 面试——IP地址你了解多少?
目录 前言 1、IP地址 1.1、什么是IP地址 1.2、IP地址的格式 1.2.1、32位二进制数表示IP地址,够用吗? 1.3、IP地址的组成 1.4、为什么会出现IPv6 1.4.1、为什么IPv6还没有大量普及呢? 1.5、子网掩码 1.6、特殊的IP地址 2、路由选择 …...

Gluten 首次开源技术沙龙成功举办,更多新能力值得期待
2023年2月17日,由 Kyligence 主办的 Gluten 首次开源技术沙龙在上海成功举办,本期沙龙特邀来自 Intel、BIGO、eBay、阿里、华为和 Kyligence 等行业技术专家齐聚一堂,共同探讨了向量化执行引擎框架 Gluten 现阶段社区的重点开发成果和未来的发…...

springboot+redis+lua实现限流
Redis 除了做缓存,还能干很多很多事情:分布式锁、限流、处理请求接口幂等性。。。太多太多了~今天想和小伙伴们聊聊用 Redis 处理接口限流。1. 准备工作首先我们创建一个 Spring Boot 工程,引入 Web 和 Redis 依赖,同时…...

线段树总结
文章目录参考文档题目线段树实现单点修改,区间求值模板题目308. 二维区域和检索 - 可变区间修改,区间求值1. 掉落的方块(区间开点)2. 维护序列3. 一个简单的问题24. 天际线问题动态开点1. 区间和个数(单点修改开点)问题以及注意事…...

龙芯GS232(MIPS 32)架构cache管理笔记
1 mips32架构 MIPS架构是一种基于精简指令集(Reduced Instruction Set Computer,RISC)的计算机处理器架构。MIPS架构由MIPS Technologies公司在1981年开发,并在1984年发布了第一款MIPS处理器。 MIPS架构的特点包括: …...

js去重
<script>let arr [{ id: 0, name: "张三" },{ id: 1, name: "李四" },{ id: 2, name: "王五" },{ id: 3, name: "赵六" },{ id: 1, name: "孙七" },{ id: 2, name: "周八" },{ id: 2, name: "吴九&qu…...