【flink SQL基础|概念】flink sql之时态表:join时要使用proctime作为时态表的time

flink版本1.12.5

1. 时态表

看下官网的定义

时态表(Temporal Table)代表基于表的(参数化)视图概念,该表记录变更历史,该视图返回表在某个特定时间点的内容。

“时”代表一个时间点,那“态”就代表着这一时刻表的状态,那时态表可以简单认为:这一时刻查询这张表的结果(或是快照)。举个例子:mysql表中11点更新了一条数据,那11点前后查询的结果是不同的,所以时态表(Temporal Table)是一张随时间变化的表。

 
Flink 使用 SQL:2011 中提出的 FOR SYSTEM_TIME AS OF 的 SQL 语法查询时态表。目前,时态表只能在 join 中使用。

接下来我们看一个join的例子
 

2. join的例子

CREATE TABLE `send_table01` (
   `id` INTEGER,
   `address` STRING,
   `cloud_wise_proc_time` AS `proctime`(),
   `cloud_wise_event_time` TIMESTAMP(3),
   WATERMARK FOR `cloud_wise_event_time` AS `cloud_wise_event_time` - INTERVAL '1' MINUTE
 ) WITH (
   'connector' = 'kafka',
   'topic' = 'topic_source_004',
   'properties.bootstrap.servers' = '10.0.16.44:18108',
   'properties.max.poll.records' = '5000',
   'properties.group.id' = 'wrwrwrw',
   'format' = 'json',
   'json.ignore-parse-errors' = 'true',
   'scan.startup.mode' = 'latest-offset'
 );

CREATE TABLE `send_table02` (
   `name` STRING,
   `id` INTEGER,
   PRIMARY KEY (`id`) NOT ENFORCED
 ) WITH (
   'connector' = 'jdbc',
   'driver' = 'ru.yandex.clickhouse.ClickHouseDriver',
   'url' = 'jdbc:clickhouse://10.101.1.234:18100/docp?socket_timeout=900000',
   'username' = 'default'
   'table-name' = 'pop'
 );

CREATE TABLE `out_table` (
   `name` STRING NOT NULL
 ) WITH (
   'connector' = 'kafka',
   'topic' = 'topic_out_60',
   'properties.bootstrap.servers' = '10.0.16.44:18108',
   'properties.acks' = '1',
   'properties.retries' = '0',
   'properties.batch.size' = '16348',
   'properties.linger.ms' = '0',
   'properties.buffer.memory' = '33554432',
   'json.ignore-parse-errors' = 'true',
   'format' = 'json'
 );

INSERT INTO `out_table`
 (SELECT `b`.`name` AS `name`
 FROM `send_table01` AS `a`
 INNER JOIN `send_table02` FOR SYSTEM_TIME AS OF `a`.`cloud_wise_proc_time` AS `b` ON `a`.`id` = `b`.`id`);

注意:

INNER JOIN `send_table02` FOR SYSTEM_TIME AS OF `a`.`cloud_wise_proc_time` AS `b` 

cloud_wise_proc_time字段要为处理时间,对于上述例子,当flink消费kafka的数据然后通过关联字段查询mysql时,flink 将cloud_wise_proc_time作为时态表的"时"去查询。也就是:kafka来一条数据的时刻作为查询mysql(时态表)的“时”。

如果选择kafka数据中事件时间作为时态表的“时”,假设数据中有事件时间为去年某刻,此时flink可能会报错,因为去年这张mysql表还不存在。

所以,针对于这样的维表join场景,当flink报相关错误时,可以考虑是否是时间类型用错了

Event-Time Temporal Table Join requires both primary key and row time attribute in versioned table, but no row time attribute can be found.
org.apache.flink.table.api.ValidationException: Event-Time Temporal Table Join requires both primary key and row time attribute in versioned table, but no row time attribute can be found.
	at org.apache.flink.table.planner.plan.rules.logical.LogicalCorrelateToJoinFromGeneralTemporalTableRule.onMatch(LogicalCorrelateToJoinFromTemporalTableRule.scala:285) ~[flink-table-blink_2.11-1.12.5.jar:1.12.5]
	at org.apache.calcite.plan.AbstractRelOptPlanner.fireRule(AbstractRelOptPlanner.java:333) ~[flink-table-blink_2.11-1.12.5.jar:1.12.5]
	at org.apache.calcite.plan.hep.HepPlanner.applyRule(HepPlanner.java:542) ~[flink-table-blink_2.11-1.12.5.jar:1.12.5]
	at org.apache.calcite.plan.hep.HepPlanner.applyRules(
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
您好!对于 Flink SQL 中的一张和维的全量 Join,可以使用 FlinkTable API 或 SQL 语句来实现。下面是使用 Table API 的示例代码: ```java // 导入所需的类 import org.apache.flink.api.common.typeinfo.Types; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.table.api.EnvironmentSettings; import org.apache.flink.table.api.Table; import org.apache.flink.table.api.TableEnvironment; import org.apache.flink.table.functions.TableFunction; import org.apache.flink.table.types.DataType; import org.apache.flink.table.types.logical.LogicalType; import org.apache.flink.types.Row; // 创建一个维函数 class DimensionTableFunction extends TableFunction<Row> { private final Tuple2<String, Integer>[] dimensionData = new Tuple2[]{ Tuple2.of("维度1", 1), Tuple2.of("维度2", 2), Tuple2.of("维度3", 3) }; public void eval(String key) { for (Tuple2<String, Integer> data : dimensionData) { if (data.f0.equals(key)) { collect(Row.of(data.f0, data.f1)); } } } @Override public DataType getResultType(Object[] arguments, LogicalType[] argumentLogicalTypes) { return DataTypes.ROW( DataTypes.FIELD("dimension_key", Types.STRING), DataTypes.FIELD("dimension_value", Types.INT) ).getLogicalType(); } } // 创建 Flink 执行环境和 TableEnvironment EnvironmentSettings settings = EnvironmentSettings.newInstance().inBatchMode().build(); TableEnvironment tEnv = TableEnvironment.create(settings); // 注册一张主 Table mainTable = tEnv.fromValues( DataTypes.ROW( DataTypes.FIELD("main_key", Types.STRING), DataTypes.FIELD("main_value", Types.INT) ), Row.of("维度1", 10), Row.of("维度2", 20), Row.of("维度3", 30) ).as("main_table"); // 注册维函数 tEnv.registerFunction("dimension_table", new DimensionTableFunction()); // 使用 SQL 进行全量 Join Table result = tEnv.sqlQuery( "SELECT m.main_key, m.main_value, d.dimension_key, d.dimension_value " + "FROM main_table AS m " + "LEFT JOIN LATERAL TABLE(dimension_table(m.main_key)) AS d " + "ON TRUE" ); // 打印结果 tEnv.toRetractStream(result, Row.class).print(); // 执行作业 tEnv.execute("Full Join Example"); ``` 这个示例代码中,我们首先创建了一个维函数 `DimensionTableFunction`,然后使用 FlinkTable API 注册了一张主 `main_table` 和维函数 `dimension_table`。最后,使用 SQL 语句进行全量 Join 操作,并将结果打印出来。您可以根据实际情况修改示例中的数据和字段名。希望对您有所帮助!如果有任何疑问,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

roman_日积跬步-终至千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值