Flink Table API & SQL - 概念和通用API

Table API 和 SQL 集成在一个 API 中。这个 API 用作查询、输入和输出的表。本文档展示了带有 Table API 和 SQL 查询的程序的公共结构、如何注册表、如何查询表以及如何写入表。

目录

两个Planner之间的主要区别

Table API and SQL的结构

创建一个TableEnvironment

在 Calalog 中注册表

注册 Table

注册 TableSource

注册 TableSink

注册外部Calalog

查询表

Table API

SQL

混合使用 Table API & SQL

写表

转化并执行查询

Old Planner

Blink Planner

与DataStream和DataSet API集成

Scala的隐式转换

将DataStream和DataSet注册为表

将DataStream和DataSet转换为表

将表转换为DataStream或DataSet

将表转换为DataStream

将表转换为DataSet

数据类型到表模式的映射

基于位置映射

基于名称映射

原子类型

元组(Scala和Java)和Case类(仅限Scala)

POJO (Java and Scala)

Row

优化查询

解释表


 

两个Planner之间的主要区别

  1. Blink 将批作业看作一个特殊的流。因此,Table 和 DataSet 之间不能转换,批处理作业不会被转换为 DateSet 程序,而是转换为 DataStream 程序,与流作业相同。
  2. Blink planner 不支持 BatchTableSource,所以要使用 StreamTableSource。
  3. Blink planner 支持新的 Catalog,不支持 ExternalCatalog。
  4. 旧 planner 和 Blink planner 的 FilterableTableSource 实现是互不兼容的,旧的把 PlannerExpressions 下发给 FilterableTableSource,Blink planner 下发给 Expressions。
  5. 基于字符串的键值配置选项仅用于 Blink planner,详情参阅://TODO。
  6. 两个 planner 中 PlannerConfig 的实现(CalciteConfig)是不同的。
  7. Blink planner 将优化多个 sink 到一个 DAG 中(只支持 TableEnvironment)。旧 planner 一个 sink 对应一个新的 DAG,每个 DAG 都是相对独立的。
  8. 旧 planner 不支持 catalog,Blink planner支持。

Table API and SQL的结构

所有用于批处理和流处理的 Table API & SQL 程序都遵循相同的模式。下面的代码示例显示了 Table API & SQL 程序的公共结构。

// create a TableEnvironment for specific planner batch or streaming
val tableEnv = ... // see "Create a TableEnvironment" section
 
// register a Table
tableEnv.registerTable("table1", ...)           // or
tableEnv.registerTableSource("table2", ...)     // or
tableEnv.registerExternalCatalog("extCat", ...)
// register an output Table
tableEnv.registerTableSink("outputTable", ...);
 
// create a Table from a Table API query
val tapiResult = tableEnv.scan("table1").select(...)
// create a Table from a SQL query
val sqlResult  = tableEnv.sqlQuery("SELECT ... FROM table2 ...")
 
// emit a Table API result Table to a TableSink, same for SQL result
tapiResult.insertInto("outputTable")
 
// execute
tableEnv.execute("scala_job")

注意:Table API & SQL 查询可以很容易地与 DataStream 或 DataSet 程序集成并嵌入其中。查阅下方:与DataStream和DataSet API集成,了解如何将数据流和数据集转换为表。

创建一个TableEnvironment

TableEnvironment 是 Table API & SQL 集成的核心概念。负责::

  • 在内部 catalog 中注册表
  • 注册catalog
  • 执行 SQL 查询
  • 注册用户自定义函数(scalar, table, or aggregation)
  • 将 DataStream 或 DataSet 转换为表
  • 保存对 ExecutionEnvironment 或 StreamExecutionEnvironment 的引用

 表总是绑定在特定的 TableEnvironment 上,在同一个查询中组合不同 TableEnvironment 的表是不可能的,例如,join 或 union 它们。

使用 StreamExecutionEnvironment 或 ExecutionEnvironment 和可选的 TableConfig 调用静态 BatchTableEnvironment.create()或 StreamTableEnvironment .create()方法创建 TableEnvironment。TableConfig 可以用来配置 TableEnvironment 或 自定义优化查询(详情见下:查询优化

BatchTableEnvironment/StreamTableEnvironment 指定匹配的 planner。

如果两个 planner 的jar都存在,则需要在程序中显式指定 planner,如下:

// **********************
// FLINK STREAMING QUERY
// **********************
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.table.api.EnvironmentSettings
import org.apache.flink.table.api.scala.StreamTableEnvironment
 
val fsSettings = EnvironmentSettings.newInstance().useOldPlanner().inStreamingMode().build()
val fsEnv = StreamExecutionEnvironment.getExecutionEnvironment
val fsTableEnv = StreamTableEnvironment.create(fsEnv, fsSettings)
// or val fsTableEnv = TableEnvironment.create(fsSettings)
 
// ******************
// FLINK BATCH QUERY
// ******************
import org.apache.flink.api.scala.ExecutionEnvironment
import org.apache.flink.table.api.scala.BatchTableEnvironment
 
val fbEnv = ExecutionEnvironment.getExecutionEnvironment
val fbTableEnv = BatchTableEnvironment.create(fbEnv)
 
// **********************
// BLINK STREAMING QUERY
// **********************
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.table.api.EnvironmentSettings
import org.apache.flink.table.api.scala.StreamTableEnvironment
 
val bsEnv = StreamExecutionEnvironment.getExecutionEnvironment
val bsSettings = EnvironmentSettings.newInstance().useBlinkPlanner().inStreamingMode().build()
val bsTableEnv = StreamTableEnvironment.create(bsEnv, bsSettings)
// or val bsTableEnv = TableEnvironment.create(bsSettings)
 
// ******************
// BLINK BATCH QUERY
// ******************
import org.apache.flink.table.api.{EnvironmentSettings, TableEnvironment}
 
val bbSettings = EnvironmentSettings.newInstance().useBlinkPlanner().inBatchMode().build()
val bbTableEnv = TableEnvironment.create(bbSettings)
 

注意:如果/lib目录中只有一个planner jar,那么可以使用 useAnyPlanner(use_any_planner for python)创建特定的 EnvironmentSettings

在 Calalog 中注册表

TableEnvironment 维护按名称注册的表的目录。有两种类型的表,输入表和输出表。输入表可以在 Table API & SQL 查询中引用,并提供输入数据。输出表可用于将 Table API & SQL 查询的结果输出到外部系统。

输入表的注册支持各种各样的数据源:

  • 现有表对象,通常是 Table API & SQL 查询的结果。
  • 一个 TableSource,访问外部数据,例如一个文件,数据库,消息系统。
  • DataStream(仅用于流任务) 和 DataSet(仅用于从旧 planner 转换的批作业) 程序中的 DataStream 和 DataSet。注册 DataStream 和 DataSet 查阅下方:与DataStream和DataSet API集成

使用 TableSink 注册输入表。

注册 Table

 
  1. // get a TableEnvironment

  2. val tableEnv = ... // see "Create a TableEnvironment" section

  3.  
  4. // table is the result of a simple projection query

  5. val projTable: Table = tableEnv.scan("X").select(...)

  6.  
  7. // register the Table projTable as table "projectedTable"

  8. tableEnv.registerTable("projectedTable", projTable)

  9.  

 注意:注册表的处理类似于关系数据库系统中的视图,即,定义表的查询未进行优化,但当另一个查询引用已注册表时,将内联该查询。如果多个查询引用了相同注册表,它将为每个引用查询内联并执行多次,即,已注册表的结果将不会共享。 

注册 TableSource

TableSource提供了访问外部数据,诸如,数据库(MySQL, HBase, …),特定编码的文件(CSV, Apache [Parquet, Avro, ORC], …),消息系统(Apache Kafka, RabbitMQ, …)。

Flink 旨在为常见的数据格式和存储系统提供 TableSources。查阅://TODO,了解支持的 Table Source 列表及如何构建自定义 Table Source。

 
  1. // get a TableEnvironment

  2. val tableEnv = ... // see "Create a TableEnvironment" section

  3.  
  4. // create a TableSource

  5. val csvSource: TableSource = new CsvTableSource("/path/to/file", ...)

  6.  
  7. // register the TableSource as table "CsvTable"

  8. tableEnv.registerTableSource("CsvTable", csvSource)

注意:用于 Blink planner 的 TableEnvironment 只接受 StreamTableSource、LookupableTableSource 和 InputFormatTableSource,并且必须绑定用于批量 Blink planner 的流表资源。 

注册 TableSink

已注册的 TableSink 可以用于将 Table API & SQL 查询的结果输出到外部存储系统,诸如,数据库(MySQL, HBase, …),特定编码的文件(CSV, Apache [Parquet, Avro, ORC], …),消息系统(Apache Kafka, RabbitMQ, …)。

 
  1. // get a TableEnvironment

  2. val tableEnv = ... // see "Create a TableEnvironment" section

  3.  
  4. // create a TableSink

  5. val csvSink: TableSink = new CsvTableSink("/path/to/file", ...)

  6.  
  7. // define the field names and types

  8. val fieldNames: Array[String] = Array("a", "b", "c")

  9. val fieldTypes: Array[TypeInformation[_]] = Array(Types.INT, Types.STRING, Types.LONG)

  10.  
  11. // register the TableSink as table "CsvSinkTable"

  12. tableEnv.registerTableSink("CsvSinkTable", fieldNames, fieldTypes, csvSink)

注册外部Calalog

外部目录可以提供关于外部数据库和表的信息,比如它们的名称、模式、统计信息,以及如何访问存储在外部数据库、表或文件中的数据的信息。

外部目录可以通过实现 ExternalCatalog 接口创建,并在 TableEnvironment 中注册样例如下:

 
  1. // get a TableEnvironment

  2. val tableEnv = ... // see "Create a TableEnvironment" section

  3.  
  4. // create an external catalog

  5. val catalog: ExternalCatalog = new InMemoryExternalCatalog

  6.  
  7. // register the ExternalCatalog catalog

  8. tableEnv.registerExternalCatalog("InMemCatalog", catalog)

在 TableEnvironment 中注册后,可以通过指定 Table API 或 SQL 查询的完整路径(如:catalog.database.table)访问 ExternalCatalog 中定义的所有表。

目前,Flink 提供了一个用于演示和测试目的的 InMemor

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值