Flink 系列之二十四 - Flink SQL - 基础操作

之前做过数据平台,对于实时数据采集,使用了Flink。现在想想,在数据开发平台中,Flink的身影几乎无处不在,由于之前是边用边学,总体有点混乱,借此空隙,整理一下Flink的内容,算是一个知识积累,同时也分享给大家。

注意由于框架不同版本改造会有些使用的不同,因此本次系列中使用基本框架是 Flink-1.19.x,Flink支持多种语言,这里的所有代码都是使用java,JDK版本使用的是19
代码参考:https://github.com/forever1986/flink-study.git

上一章对FlinkSQL基本入门及其其中的原理进行了讲解。这一章先从FlinkSQL的基础开始讲起,为了是那些没有什么标准SQL基础的朋友,如果你有基础,直接可以跳过第一部分。第二部分按照前面Data Stream API的顺序,开始讲解在sql-client中如何设置执行环境。不记得的话可以回顾一下《系列之五 - Data Stream API的执行环境》中的内容。最后一部分讲解一下sql-client工具的显示模式,只是为了后续演示或者开发过程中的方便。

1 建库建表操作

如果学过标准SQL语法的朋友,那么这一部分可以不用看或者快速过一遍。其语法与标准SQL 相差不大,主要的部分细微差别。

1.1 建库操作

熟悉关系型数据库的朋友可能知道,有些关系型数据库比如oracle就分3层:命名空间(schema)–数据库(database)–表(table)。在FlinkSQL中同样也分三层。目录(catalog)–数据库(database)–表(table)。关于目录(catalog)部分,它与关联实际数据库相关,后续再讲解,这里只需要知道有一个默认的default_catalog即可。

1)查看数据库

show databases;
show current database;

在这里插入图片描述

2)建立数据库

# 语法
CREATE DATABASE [IF NOT EXISTS] [catalog_name.]db_name
  [COMMENT database_comment]
  WITH (key1=val1, key2=val2, ...)
# 测试示例
create database test;

在这里插入图片描述

3)删除数据库

# 语法
DROP DATABASE [IF EXISTS] [catalog_name.]db_name [ (RESTRICT | CASCADE) ]
# 测试示例
drop database if exists test;

在这里插入图片描述

注意:删除数据库可以加上关键字RESTRICT表示如果库里面有表,则不允许删除(这是默认的)。如果加上关键字CASCADE则会删除库里面的所有表和函数。

更详细的语法,可以参考《官方文档

1.2 建表操作

1.2.1 基本语法

创建表的语句语法与关系型数据库的SQL基本一致,只不过增加一些Connector的语法(也就是WITH部分)

CREATE TABLE [IF NOT EXISTS] [catalog_name.][db_name.]table_name
  (
    { <physical_column_definition> | <metadata_column_definition> | <computed_column_definition> }[ , ...n]
    [ <watermark_definition> ]
    [ <table_constraint> ][ , ...n]
  )
  [COMMENT table_comment]
  [PARTITIONED BY (partition_column_name1, partition_column_name2, ...)]
  WITH (key1=val1, key2=val2, ...)
  [ LIKE source_table [( <like_options> )] | AS select_query ]

说明:

  • 1)IF NOT EXISTS:加上表示不存在则创建,存在则不创建。这样如果表已存储,则不会报错。
  • 2)[catalog_name.][db_name.]table_name : 目录名+数据库名+表名。其中 目录名+数据库名可以不填写,则默认当前目录和数据库。
  • 3)physical_column_definition:列名定义,physical_column_definition是定义常规的列。语法如下:
column_name column_type [ <column_constraint> ] [COMMENT column_comment]
# 其中<column_constraint> 的语法如下:
  [CONSTRAINT constraint_name] PRIMARY KEY NOT ENFORCED
# PRIMARY KEY 表示唯一主键,NOT ENFORCED是表示不强制
  • 4)metadata_column_definition:列名定义,metadata_column_definition是定义来之Connector的元数据类,这个后面讲Connector时会讲。语法如下:
column_name column_type METADATA [ FROM metadata_key ] [ VIRTUAL ]
# 其中VIRTUAL 表示该列不持久化
  • 5)computed_column_definition:列名定义,computed_column_definition为计算列,也就是可以定义一个通过简单计算得出来的列,比如在某一列基础上加上某个值。语法如下:
column_name AS computed_column_expression [COMMENT column_comment]
WATERMARK FOR rowtime_column_name AS watermark_strategy_expression
  • 7)table_constraint:语法如下:
[CONSTRAINT constraint_name] PRIMARY KEY (column_name, ...) NOT ENFORCED
  • 8)PARTITIONED BY :用于创建分区。语法如下:
PARTITIONED BY (partition_column_name1, partition_column_name2, ...)
  • 9)WITH :连接器,前面讲解Data Stream API的输入和输出算子中就讲到连接器,而SQL API也是可以定义这些连接器。下面是一个kafka的connector示例:
CREATE TABLE KafkaTable (
  `user_id` BIGINT,
  `item_id` BIGINT,
  `behavior` STRING,
  `ts` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp'
) WITH (
  'connector' = 'kafka',
  'topic' = 'user_behavior',
  'properties.bootstrap.servers' = 'localhost:9092',
  'properties.group.id' = 'testGroup',
  'scan.startup.mode' = 'earliest-offset',
  'format' = 'csv'
)
  • 10)LIKE:基于现有的表,创建新的表。语法如下:
LIKE source_table [( <like_options> )]
  • 11)AS:基于查询语句,创建新的表。语法如下:
AS select_query

使用AS创建表,还有一些限制如下:
① 目前还不支持创建临时表。
② 尚不支持指定显式列。
③ 尚不支持指定显式水印。
④ 不支持创建分区表。
⑤ 尚不支持指定主键约束。

  • 12)列的类型:Flink中定义的表的列的类型,可以参考《官方文档

当然,这里面有很多细节在后面会详细的讲解,这里就先了解基本的创建语句。下面也通过简单的几个创建表的操作来加深一下印象。

1.2.2 示例演示

示例说明:这里通过创建一个基于print的输出表,然后插入数据,在控制台看看数据是否到print输出算子中

1)创建一个写入print输出算子的表

CREATE TABLE log(
	id STRING,
	cpu DOUBLE,
	ts INT
) WITH (
'connector' = 'print'
);

在这里插入图片描述

2)查看刚才新建的log表

desc log;

在这里插入图片描述

这里说明一下表格的含义:name为列名,type为类型,null为是否可空,key为主键,extras为格外属性,watermark为水位线

3)使用like创建log_copy表

CREATE TABLE log_copy(memory DOUBLE) LIKE log;

在这里插入图片描述

4)查看log_copy表

desc log_copy;

在这里插入图片描述

5)往log表插入数据

insert into log values('server1',20.4,1);

在这里插入图片描述

注意:这里可以看到当插入数据时,会生成一个Job任务。可以同Web-UI的控制台看到该任务,以及在控制台输出日志:
在这里插入图片描述
输出日志如下:
在这里插入图片描述

如果你对log进行select的时候会报错,这是因为print这个的Connector只支持sink,因此sink可以插入,但是不能select。这一块后续关于源算子、输出算子相关的Connector时会讲到。

上面只是简单演示了SQL在Flink的sql-client客户端工具的使用,接下来讲解如何在sql-client中设置执行环境。在前面的Data Stream API中《系列之五 - Data Stream API的执行环境》会设置一些执行环境设置,如果不记得可以回顾一下这章。

2 执行环境

在Data Stream API中《系列之五 - Data Stream API的执行环境》会设置一些执行环境设置,那么在SQL API方式下,如何设置:

1)执行环境:在Data Stream API中可以设置流处理或者批处理,在SQL API设置如下:

SET execution.runtime-mode=streaming; # streaming是默认,如果批处理使用batch

2)并行度:设置默认并行度

SET parallelism.defaut=1;

3)状态TTL:设置状态的过期时间,这个很重要,在SQL API中,很多操作其实都会存储状态,需要根据业务定时清理,不然会导致内存溢出。

SET parallelism.defaut=1;

4)显示模式:这是是执行结果的查询,特别是select语句,由于Flink的数据是流,因此select结果其实一个是连续查询的动态表,因此需要客户端可以刷新查看结果。在Flink中提供三种模式,这个在下一部分独立讲解

SET sql-clent.execution.result-mode=TABLE; # 支持TABLE(默认)、CHANGELOG、TABLEAU

其它参数可以参考《官方文档中Configuration

3 显示模式

在使用SQL API过程中,经常会先通过select语句测试一下要执行的步骤是否正确,这对研发过程非常重要。sql-client客户端工具提供3种select可视化的显示模式。在此之前,先准备一下工作,下面SQL脚本相当于创建一个来之自动生成数字的源算子:

CREATE TABLE log(
	id INT,
	cpu DOUBLE,
	ts INT
) WITH (
  'connector' = 'datagen',
  'rows-per-second'='1',
  'fields.id.kind'='random',
  'fields.id.min'='1',
  'fields.id.max'='5',
  'fields.cpu.kind'='random',
  'fields.cpu.min'='1',
  'fields.cpu.max'='100',
  'fields.ts.kind'='sequence',
  'fields.ts.start'='1',
  'fields.ts.end'='100000'
);

在这里插入图片描述

3.1 TABLE显示模式

这个是是默认模式,不需要设置:

select * from log;

结果如下:
在这里插入图片描述

从上面的图可以看到。和关系型数据库的客户端工具基本上一致,就是一张表,会不断刷新,可以翻页等功能

3.2 CHANGELOG显示模式

SET sql-client.execution.result-mode=CHANGELOG; 
select * from log;

在这里插入图片描述

从上面的图可以看到。这边多了一个OP的字段,这是一个显示追加的标志,+I表示插入,-U表示回撤,+U表示更新

3.3 TABLEAU显示模式

SET sql-client.execution.result-mode=TABLEAU; 
select * from log;

在这里插入图片描述

从上面的图可以看到。界面不会跳到另外一个页面,其显示基本跟CHANGELOG模式一样

结语:本章通过基础的建库建表、执行环境配置以及显示模式演示,这些都是为了后面做基础,接下来就按照Data Stream API 方式来讲解在SQL API中如何实现对应功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

linmoo1986

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

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

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

打赏作者

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

抵扣说明:

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

余额充值