flink之table和SQL
table与SQL的基本介绍
在Spark中有DataFrame这样的关系型编程接口,因其强大且灵活的表达能力,能够让用户通过非常丰富的接口对数据进行处理,有效降低了用户的使用成本。
Flink也提供了关系型编程接口 Table API 以及基于Table API 的 SQL API,让用户能够通过使用结构化编程接口高效地构建Flink应用。同时Table API 以及 SQL 能够统一处理批量和实时计算业务, 无须切换修改任何应用代码就能够基于同一套 API 编写流式应用和批量应用,从而达到真正意义的批流统一。
- Flink有两个关系型API: Table API和SQL,用于统一流处理和批处理
- Table API 是用于 Scala 和 Java 语言的查询API,允许以非常直观的方式组合关系运算符的查询,例如 select,filter 和 join。
- Flink SQL 的支持是基于实现了SQL标准的 Apache Calcite。无论输入是批输入(DataSet)还是流输入(DataStream),任一接口中指定的查询都具有相同的语义并指定相同的结果。
- Table API和SQL接口彼此集成,Flink的DataStream和DataSet API亦是如此。我们可以轻松地在基于API构建的所有API和库之间切换。
注意
到目前最新版本为止,Table API和SQL还有很多功能正在开发中。 并非[Table API,SQL]和[stream,batch]输入的每种组合都支持所有操作
为什么需要SQL
-
Table API 是一种关系型API,类 SQL 的API,用户可以像操作表一样地操作数据(即关系型API), 非常的直观和方便。
-
SQL 作为一个"人所皆知"的语言,如果一个引擎提供 SQL,它将很容易被人们接受。这已经是业界很常见的现象了。
-
Table & SQL API 还有另一个职责,就是流处理和批处理统一的API层。
开发环境构建
-
在 Flink 1.9 中,Table 模块迎来了核心架构的升级,引入了阿里巴巴 Blink 团队贡献的诸多功能,取名叫: Blink Planner。
-
在使用 Table API 和 SQL 开发 Flink 应用之前,通过添加 Maven 的依赖配置到项目中,在本地工程中引入相应的依赖库,库中包含了 Table API 和 SQL 接口。
-
添加pom依赖
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-planner_2.11</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-api-scala-bridge_2.11</artifactId>
<version>1.9.2</version>
</dependency>
TableEnvironment
TableEnvironment用来创建关系型编程环境。TableEnvironment 中提供了
- 注册内部表
- 执行 Flink SQL 语句
- 注册自定义函数等功能。
根据应用类型的不同,TableEnvironment 创建方式也有所不同,但是都是通过调用 create()方法创建
流计算环境下创建 TableEnviroment
//初始化Flink的Streaming(流计算)上下文执行环境
val streamEnv: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
//初始化Table API的上下文环境
val tableEvn =StreamTableEnvironment.create(streamEnv)
在 Flink1.9 之后由于引入了 Blink Planner
val bsSettings = EnvironmentSettings.newInstance().useOldPlanner().inStreamingMode().build()
val bsTableEnv = StreamTableEnvironment.create(streamEnv, bsSettings)
注意
Flink 社区完整保留原有 Flink Planner (Old Planner),同时又引入了新的Blink Planner,用户可以自行选择使用 Old Planner 还是 Blink Planner。官方推荐暂时使用 Old Planner
Table API
在 Flink 中创建一张表有两种方法:
- 从一个文件中导入表结构(Structure)(常用于批计算)(静态)
- 从 DataStream 或者 DataSet 转换成 Table (动态)
创建 Table
Table API 中已经提供了 TableSource 从外部系统获取数据,例如常见的数据库、文件
系统和 Kafka 消息队列等外部系统。
从文件中创建 Table(静态表)
需求
- 读取csv文件,文件内容参见课件当中的flinksql.csv文件,查询年龄大于18岁的人,并将结果写入到csv文件里面去,这里涉及到flink的connect的各种与其他外部系统的连接,参见
官网链接:Connect to External Systems
代码示例
import org.apache.flink.api.common.typeinfo.TypeInformation
import org.apache.flink.core.fs.FileSystem.WriteMode
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.table.api.{
Table, Types}
import org.apache.flink.table.api.scala.StreamTableEnvironment
import org.apache.flink.table.sinks.CsvTableSink
import org.apache.flink.table.sources.CsvTableSource
object table_static {
def main(args: Array[String]): Unit = {
//构建流处理环境
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
//构建tableEnvironment
val tableEnvironment: StreamTableEnvironment = StreamTableEnvironment.create(env)
//构建CSV数据源
val source: CsvTableSource = CsvTableSource.builder()
.path("F:\\BigData\\data\\flinksql.csv")
.field("id", Types.INT())
.field("name", Types.STRING())
.field("age", Types.INT())
.fieldDelimiter(