时态表
时态表(Temporal Table)是一张随时间变化的表 – 在 Flink 中称为动态表,时态表中的每条记录都关联了一个或多个时间段,所有的 Flink 表都是时态的(动态的)
时态表包含表的一个或多个有版本的表快照,时态表可以是一张跟踪所有变更记录的表(例如数据库表的 changelog,包含多个表快照),也可以是物化所有变更之后的表(例如数据库表,只有最新表快照)。
版本: 时态表可以划分成一系列带版本的表快照集合,表快照中的版本代表了快照中所有记录的有效区间,有效区间的开始时间和结束时间可以通过用户指定,根据时态表是否可以追踪自身的历史版本与否,时态表可以分为 版本表
和 普通表
。
版本表: 如果时态表中的记录可以追踪和并访问它的历史版本,这种表我们称之为版本表,来自数据库的 changelog (如mysql binlog)可以定义成版本表,版本表内的数据始终不会自动清理,只能通过upsert触发。
普通表: 如果时态表中的记录仅仅可以追踪并和它的最新版本,这种表我们称之为普通表,来自数据库 或 HBase 、redis的表可以定义成普通表。
Flink 使用主键约束和事件时间来定义一张版本表和版本视图。
声明版本表
在 Flink 中,定义了主键约束和事件时间属性的表就是版本表。
CREATE TABLE product_changelog (
product_id STRING,
product_name STRING,
product_price DECIMAL(10, 4),
update_time TIMESTAMP(3) METADATA FROM 'value.source.timestamp' VIRTUAL,
PRIMARY KEY(product_id) NOT ENFORCED, -- (1) 定义主键约束
WATERMARK FOR update_time AS update_time -- (2) 通过 watermark 定义事件时间
) WITH (
'connector' = 'kafka',
'topic' = 'products',
'scan.startup.mode' = 'earliest-offset',
'properties.bootstrap.servers' = 'localhost:9092',
'value.format' = 'debezium-json'
);
声明版本视图
Flink 也支持定义版本视图只要一个视图包含主键和事件时间便是一个版本视图。
注意,此时RatesHistory
并每一设置主键,在声明视图时,通过去重查询
定义版本视图, 去重查询可以产出一个有序的 changelog 流,去重查询产生主键并保留原始数据流的事件时间属性。
-- 定义一张 append-only 表
CREATE TABLE RatesHistory (
currency_time TIMESTAMP(3),
currency STRING,
rate DECIMAL(38, 10),
WATERMARK FOR currency_time AS currency_time -- 定义事件时间
) WITH (
'connector' = 'kafka',
'topic' = 'rates',
'scan.startup.mode' = 'earliest-offset',
'properties.bootstrap.servers' = 'localhost:9092',
'format' = 'json' -- 普通的 append-only 流
)
CREATE VIEW versioned_rates AS
SELECT currency, rate, currency_time -- (1) `currency_time` 保留了事件时间
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY currency -- (2) `currency` 是去重 query 的 unique key,可以作为主键
ORDER BY currency_time DESC) AS rowNum
FROM RatesHistory )
WHERE rowNum = 1;
声明普通表
用 DDL 定义一张 HBase 表,然后我们可以在 SQL 中将其当作一张时态表使用。实现LookupableTableSource
接口的表。
-- 'currency' 列是 HBase 表中的 rowKey
CREATE TABLE LatestRates (
currency STRING,
fam1 ROW<rate DOUBLE>
) WITH (
'connector' = 'hbase-1.4',
'table-name' = 'rates',
'zook
流表、维表
流表:实时流数据映射成的表,在join查询中,每来一条数据都会主动去维表中查询是否有匹配的数据。
维表:维度信息表,一般在外部存储(Redis,Mysql中)维表是被动查询的,目前Flink SQL的维表JOIN仅支持对当前时刻维表快照的关联
在 Flink 流式计算中,我们的一些维度属性一般存储在 MySQL/HBase/Redis 中,这些维表数据存在定时更新,需要我们根据业务进行关联。根据我们业务对维表数据关联的时效性要求,有以下几种解决方案:
- 实时查询维表关联
- 预加载维表关联
- 热存储关联
- 广播维表
维表是数仓中的一个概念,维表中的维度属性是观察数据的角度,补充事实表的信息。