当前位置: 首页 > news >正文

【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)&#xff1a;动态表是流的另一种表达方式&#xff0c;动态表作为一个逻辑的抽象概念&#xff0c;使我们更容易理解flink中将streaming发展到table这个层次的设计&#xff0c;本质都是对无边界、持续变更数据的表示形式&#xff0c;所以动态表与流之…...

常用正则表达式

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

PMP考试有没有什么技巧可以介绍一下么?

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

2022-2023年营销报告(B站平台) | 5大行业势态、流量大盘全景洞察

一直以来&#xff0c;手持高活跃、高粘性用户群体的B站是行业用来观察年轻人消费习惯的重要平台。以至于用户群体的不断壮大带动了B站的商业价值。如今B站的商业舞台越来越大&#xff0c;不断地向外界招手&#xff0c;欢迎更多品牌积极加入到这个千万年轻人聚集的内容社区。为了…...

Python的异常与工具包

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

基于SSM的婴幼儿商城

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

2023年新能源汽车行业研究报告

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

手写Promise方法(直击Promise A+规范)

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

GooglePlay SSL Error Handler

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

OpenStack手动分布式部署Keystone【Queens版】

目录 Keystone简介 1、登录数据库配置&#xff08;在controller执行&#xff09; 1.1登录数据库 1.2数据库里创建keystone 1.3授权对keystone数据库的正确访问 1.4退出数据库 2、数据库导入Keystone表&#xff08;在controller执行&#xff09; 2.1安装httpd mod_wsgi 2.2备…...

AAPT2

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

kafka学习

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

坐拥两条黄金赛道,爱博医疗未来必是星辰大海!

尽管2022年疫情反复&#xff0c;但爱博医疗仍交出了亮眼的“答卷”。图源&#xff1a;爱博医疗2023年2月14日晚间&#xff0c;爱博医疗披露了2022年度业绩快报&#xff0c;营收5.79亿元&#xff0c;同比增长33.81%&#xff1b;归母净利润2.32亿元&#xff0c;同比增长35.27%&am…...

DEV C++的使用入门程序做算术运算

DEV C Dev-C &#xff08;有时候也称为 Dev-Cpp&#xff09;是一个免费软件&#xff0c;最早是由 BloodShed 公司开发的&#xff0c;在版本 4.9.2 之后该公司停止开发并开放源代码。然后由 Orwell 接手进行维护&#xff0c;陆续开发了几个版本&#xff0c;后来也有其他开发人员…...

华为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 逻辑交互介绍(四)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#…...

c/c++开发,无可避免的模板编程实践(篇八)

一、借用标准库模板构造自己的模板 通常&#xff0c;模板设计是遵循当对象的类型不影响类中函数的行为时就使用模板。这也就是为何标准库提供大部分的模板都是与容器、迭代器、适配器、通用算法等有关&#xff0c;因为这些主要是除了对象集合行为&#xff0c;如读写、增删、遍历…...

Leetcode13. 罗马数字转整数

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

元宇宙对营销方式的影响

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

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...