Catalog维护了Flink Table和SQL中的元数据,如Database
、Table
、View
、UDF
等。
Catalog类型
- GenericInMemoryCatalog: 内置Catalog。名为
default_catalog
,默认数据库名为default_database
。默认,如用TableEnvironment#registerTable
注册的表,均会注册到这个Catalog中。 - User-Defined Catalog: 用户自定义
Catalog
。如flink-connector-hive
中的HiveCatalog
。
注意:
- GenericInMemoryCatalog 中的元数据对象名区分大小写。HiveCatalog以小写存储所有元数据对象名。
- 默认使用的Catalog:
default_catalog
,Database:default_database
。
Catalog使用
1. 获取当前使用的Catalog
tableEnv.getCurrentCatalog()
2. 获取当前使用的Database
tableEnv.getCurrentDatabase()
3. 注册自定义Catalog
tableEnv.registerCatalog("custom-catalog",new CustomCatalog("customCatalog"))
4. 列出所有Catalog
tableEnv.listCatalogs()
5. 列出所有Database
tableEnv.listDatabases()
6. 切换Catalog
tableEnv.useCatalog("catalogName")
7. 切换Database
tableEnv.useDatabase("databaseName")
8. 注册Table
// 将DataStream注册成Catalog中的表
tableEnv.registerDataStream(String name, DataStream<T> dataStream)
// 将计算产生的Table注册成Catalog中的表
tableEnv.registerTable(String name, Table table)
// 将外部数据源注册成Catalog中的表
// 已支持的数据源有: CsvTableSource、ParquetTableSource、HBaseTableSource、JDBCTableSource、KafkaTableSource
// 表注册后,即可用SQL对表进行查询
tableEnv.registerTableSource(String name, TableSource<?> tableSource)
// 将外部目的地注册成Catalog中的表
// 已支持的目的地有: CsvTableSink、KafkaTableSink、JDBCAppendTableSink、JDBCUpsertTableSink、HBaseUpsertTableSink、HiveTableSink
// 表注册后,即可用SQL中的Insert语句向外部存储写出数据
tableEnv.registerTableSink(String name, TableSink<?> configuredSink)
9. 注册Function
// 在Catalog中注册UDF(标量函数)
// 输入一行,输出一行
tableEnv.registerFunction(String name, ScalarFunction function)
// 在Catalog中注册UDTF
// 输入一行,输出多行
tableEnv.registerFunction(String name, TableFunction<T> tableFunction)
// 在Catalog中注册UDAF
// 输入多行,输出一行
tableEnv.registerFunction(String name, AggregateFunction<T, ACC> aggregateFunction)
// 在Catalog中注册UDAF
// 输入多行,输出多行
tableEnv.registerFunction(String name, TableAggregateFunction<T, ACC> tableAggregateFunction)
10. 列出所有Table
tableEnv.listTables()
11. 列出所有UDF
tableEnv.listUserDefinedFunctions()
12. 查询某个Table
默认,Flink在当前Catalog的Database中查找表,可用全路径catalog.database.table
指定某个表名。如下:
tableEnv.sqlQuery("select * from default_catalog.default_database.t_userInfo")
DataStream转换为Table
DataStream转换为Table有两种方式: 注册和转换。
注意: DataStream转换为Table类型会自动推导。
- 注册: 将DataStream注册成Catalog中的表,然后可以用Flink SQL对表中的数据进行查询和处理。如下:
// DataStream
DataStreamSource<Tuple2<String, Integer>> stream = streamEnv.fromElements(new Tuple2<>("name1", 10), new Tuple2<>("name2", 20));
// 将DataStream注册成Catalog中的表,表名table1,字段名为默认的f0,f1
tableEnv.registerDataStream("table1",stream);
tableEnv.toAppendStream(tableEnv.sqlQuery("select f1 from table1"), Row.class).print();
// 将DataStream注册成Catalog中的表,表名table2,字段名为name,age
tableEnv.registerDataStream("table2",stream,"name,age");
tableEnv.toAppendStream(tableEnv.sqlQuery("select name from table2"), Row.class).print();
- 转换: 将DataStream转换成Table对象,然后用Table API操作。
// DataStream
DataStreamSource<Tuple2<String, Integer>> stream = streamEnv.fromElements(new Tuple2<>("name1", 10), new Tuple2<>("name2", 20));
// 将DataStream转换成Table对象,字段名为默认的f0,f1
Table table1 = tableEnv.fromDataStream(stream);
Table tmpTable1 = table1.select("f1").where("f1 >10");
tableEnv.toAppendStream(tmpTable1, Row.class).print();
// 将DataStream转换成Table对象,字段名为name,age
Table table2 = tableEnv.fromDataStream(stream,"name,age");
Table tmpTable2 = table2.select("name").where("name ='name2'");
tableEnv.toAppendStream(tmpTable2, Row.class).print();
Table转换为DataStream
可将Table转换为Row、Tuple、POJO、Case Class等数据类型的DataStream。
Table转换为DataStream有两种模式:Append模式和Retract模式。
- Append模式: 当Table仅通过INSERT修改时使用此模式。
// DataStream
DataStreamSource<Tuple2<String, Integer>> stream = streamEnv.fromElements(new Tuple2<>("name1", 10), new Tuple2<>("name2", 20));
// 将DataStream转换成Table对象,字段名为name,age
Table table = tableEnv.fromDataStream(stream,"name,age");
// Append模式
// 转换为DataStream
tableEnv.toAppendStream(table,Row.class).print();
// 转换为DataStream
tableEnv.toAppendStream(table, Types.TUPLE(Types.STRING,Types.INT)).print();
- Retract模式: 一般都可使用此模式。通过一个Boolean类型标记当前操作类型。True代表Add(添加),False代表Retract(撤回)。
// DataStream
DataStreamSource<Tuple2<String, Integer>> stream = streamEnv.fromElements(new Tuple2<>("name1", 10), new Tuple2<>("name2", 20));
// 将DataStream转换成Table对象,字段名为name,age
Table table = tableEnv.fromDataStream(stream,"name,age");
// Retract模式
// Table转换为DataStream
DataStream<Tuple2<Boolean, Tuple>> stream1 = tableEnv.toRetractStream(table, Types.TUPLE(Types.STRING, Types.INT));
stream1.print();
// 结果
(true,(name2,20))
(true,(name1,10))
// Table转换为DataStream
DataStream<Tuple2<Boolean, Row>> stream1 = tableEnv.toRetractStream(table, Row.class);
stream1.print();
//结果
(true,name1,10)
(true,name2,20)