时态表(Temporal Table)是Flink SQL中一个非常重要的概念,它允许你查询某个时间点的表快照,特别适合处理历史数据或需要关联历史维表的场景。下面我将详细解释时态表的概念、用法和常见应用场景。
时态表是一个会随时间变化的表,它记录了数据在不同时间点的状态。在Flink SQL中,时态表通常用于以下场景:
在Flink SQL中,时态表通常通过以下方式定义:
PROCTIME()
函数,表示数据被处理的时间。WATERMARK
和event_time
字段,表示数据实际发生的时间。CREATE TEMPORARY TABLE dim_rate (
currency STRING,
rate DECIMAL(10, 2),
proctime AS PROCTIME() -- 处理时间
) WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://localhost:3306/db',
'table-name' = 'exchange_rates'
);
CREATE TEMPORARY TABLE dim_rate (
currency STRING,
rate DECIMAL(10, 2),
event_time TIMESTAMP(3),
WATERMARK FOR event_time AS event_time - INTERVAL '5' SECOND
) WITH (
'connector' = 'kafka',
'topic' = 'exchange_rates',
'properties.bootstrap.servers' = 'localhost:9092'
);
时态表的核心用法是通过FOR SYSTEM_TIME AS OF
语法查询某个时间点的表快照。
SELECT o.order_id, o.amount, r.rate
FROM orders o
JOIN dim_rate FOR SYSTEM_TIME AS OF o.proctime AS r
ON o.currency = r.currency;
SELECT o.order_id, o.amount, r.rate
FROM orders o
JOIN dim_rate FOR SYSTEM_TIME AS OF o.event_time AS r
ON o.currency = r.currency;
假设你有一个订单表和一个汇率表,汇率表会随时间变化。你可以使用时态表查询订单发生时的汇率,进行金额转换:
SELECT o.order_id, o.amount * r.rate AS amount_usd
FROM orders o
JOIN dim_rate FOR SYSTEM_TIME AS OF o.event_time AS r
ON o.currency = r.currency;
假设你有一个商品价格表,价格会随时间变化。你可以查询某个时间点的价格:
SELECT o.order_id, o.product_id, p.price
FROM orders o
JOIN dim_price FOR SYSTEM_TIME AS OF o.event_time AS p
ON o.product_id = p.product_id;
假设你有一个配置表,配置会随时间变化。你可以查询某个时间点的配置:
SELECT o.order_id, o.config_id, c.value
FROM orders o
JOIN dim_config FOR SYSTEM_TIME AS OF o.event_time AS c
ON o.config_id = c.config_id;
特性 | 时态表 | 普通表 |
---|---|---|
时间语义 | 支持处理时间和事件时间 | 仅支持处理时间 |
查询语法 | FOR SYSTEM_TIME AS OF |
普通JOIN |
适用场景 | 历史数据查询、维表关联 | 实时数据查询 |
数据一致性 | 要求按时间顺序到达 | 无特殊要求 |
时态表的实现通常基于以下技术:
原因:数据未按时间顺序到达,或时态表未正确配置时间字段。
解决方案:确保数据按时间顺序到达,并正确配置时态表的时间字段。
原因:时态表数据量大,或未做分区/索引优化。
解决方案:对时态表做分区/索引优化,或使用缓存加速查询。