flink sql

数据类型:

-- 字符串类型

# char类型
CHAR
CHAR(n) -- n在 12147483647 之间  未设置n=1
# 字符串类型
VARCHAR
VARCHAR(n)  -- n在 12147483647 之间  未设置n=1
STRING  -- 等于最大的varchar(max)
# 二进制类型
BINARY
BINARY(n) -- 范围同上
# 可变长度二进制类型
VARBINARY
VARBINARY(n)  -- 类似于string
BYTES

-- 数字类型

# 带有精度的十进制数字类型  -- 类似于java中的
DECIMAL
DECIMAL(p)
DECIMAL(p, s)

DEC
DEC(p)
DEC(p, s)

NUMERIC
NUMERIC(p)
NUMERIC(p, s)
# 带符号
TINYINT  -- -128 to 127
SMALLINT -- -32768 to 32767
# 不带符号的
INT  -- 2147483,648 to 2147483647
INTEGER
BIGINT  --  -9223372036854775808 to 9223372036854775807
# 带小数的
FLOAT
DOUBLE

-- 时间类型

#日期
DATE  -- 2020-10-12
#时间
TIME
TIME(p) -- 10:10:12.p  不指定p,p= 0
#时间戳
TIMESTAMP
TIMESTAMP(p) -- 2020-12-12 12:10:11.p

-- 其他类型
#
ARRAY<t>
t ARRAY
#map类型
MAP<kt, vt>

DDL

建表,表分为两种:

  1.  临时表:通常保存于内存中并且仅在创建它们的 Flink session(可以理解为一次 Flink 任务的运行)持续期间存在。这些表对于其它 session(即其他 Flink 任务或非此次运行的 Flink 任务)是不可见的。因为这个表的元数据没有被持久化。如下案例:
-- 临时外部表
CREATE TEMPORARY TABLE source_table (
    user_id BIGINT,
    `name` STRING
) WITH (
  'connector' = 'user_defined',
  'format' = 'json',
  'class.name' = 'flink.examples.sql._03.source_sink.table.user_defined.UserDefinedSource'
);

  1. 永久表:需要外部 Catalog(例如 Hive Metastore)来持久化表的元数据。一旦永久表被创建,它将对任何连接到这个 Catalog 的 Flink session 可见且持续存在,直至从 Catalog 中被明确删除。如下案例:
-- 永久外部表。需要外部 Catalog 持久化!!!
CREATE TABLE source_table (
    user_id BIGINT,
    `name` STRING
) WITH (
  'connector' = 'user_defined',
  'format' = 'json',
  'class.name' = 'flink.examples.sql._03.source_sink.table.user_defined.UserDefinedSource'
);
使用场景:

使用场景

临时表适用场景

  1. 临时数据分析:当需要临时处理一些中间数据,且不希望影响其他会话时

  2. 测试和调试:快速创建表结构进行SQL验证,无需持久化

  3. 会话级中间结果:在复杂查询中作为中间步骤的存储

  4. 个性化视图:为特定会话创建个性化数据视图

永久表适用场景

  1. 持久化数据存储:需要长期保存的表结构和数据

  2. 跨会话共享:多个Flink作业或会话需要访问相同表定义

  3. 生产环境应用:作为正式数据管道的一部分

  4. 与外部系统集成:需要Hive等其他系统访问的表定义


不同的数据源对应不同的连接器,可以通过官方文档查询连接器以及对应的参数。
阿里云连接器文档:https://help.aliyun.com/zh/flink/developer-reference/supported-connectors?spm=a2c4g.11186623.help-menu-45029.d_5_0_0.69cefa0c8wipPU

DQL

常用函数可以参考flink官方文档:

https://nightlies.apache.org/flink/flink-docs-release-1.13/docs/dev/table/functions/systemfunctions/

如果用的是flink官网阿里版,看阿里云的文档即可:

https://help.aliyun.com/zh/flink/developer-reference/overview-7?spm=a2c4g.11174283.help-menu-45029.d_5_2_6_0.2ede2215EXpjic&scm=20140722.H_188424._.OR_help-T_cn~zh-V_1

1.with子句

和ODPS SQL一样使用

2.select和where

和标准SQL一样使用

3.select和distinct

和离线不同,实时的去重需要保留状态,那么要么设置状态时间

state.ttl,或者根据实际情况,通过窗口和group by 去重

4.窗口表值函数TVF
核心是windows,将无限的流分为有限的流:
窗口函数分位滚动、滑动、累计窗口:TUMBLEHOPCUMULATE
示例数据源:
-- 创建Kafka源表
CREATE TABLE user_events (
    user_id BIGINT,
    item_id BIGINT,
    category_id BIGINT,
    behavior STRING,
    event_time TIMESTAMP(3),
    -- 定义事件时间属性
    WATERMARK FOR event_time AS event_time - INTERVAL '5' SECOND
) WITH (
    'connector' = 'kafka',
    'topic' = 'user_events',
    'properties.bootstrap.servers' = 'kafka:9092',
    'properties.group.id' = 'user_behavior',
    'scan.startup.mode' = 'latest-offset',
    'format' = 'json'
);
滚动窗口:

TUMBLE(TABLE data, DESCRIPTOR(timecol), size [, offset ])

返回值:

UMBLE 的返回值是一个新的关系,它包括原来表的所有列以及另外3列“window_start”,“window_end”,“window_time”来表示分配的窗口。

用于计算窗口的表,必须有时间戳字段

-- 计算每5分钟各商品的点击量
CREATE TABLE item_click_counts_5min (
    window_start TIMESTAMP(3),
    window_end TIMESTAMP(3),
    item_id BIGINT,
    click_count BIGINT,
    -- 添加处理时间,便于下游消费
    proc_time AS PROCTIME()
) WITH (
    'connector' = 'kafka',
    'topic' = 'item_click_counts_5min',
    'properties.bootstrap.servers' = 'kafka:9092',
    'format' = 'json',
    'json.ignore-null-fields' = 'false'
);

-- 将窗口计算结果插入到输出表
INSERT INTO item_click_counts_5min
SELECT 
    window_start, 
    window_end,
    item_id,
    COUNT(*) AS click_count
FROM TABLE(
    TUMBLE(TABLE user_events, DESCRIPTOR(event_time), INTERVAL '5' MINUTES)
)
WHERE behavior = 'click'
GROUP BY window_start, window_end, item_id;

滑动窗口类似用法:

-- 创建UV结果表(输出到MySQL)
CREATE TABLE user_activity_uv (
    window_start TIMESTAMP(3),
    window_end TIMESTAMP(3),
    uv BIGINT,
    PRIMARY KEY (window_start, window_end) NOT ENFORCED
) WITH (
    'connector' = 'jdbc',
    'url' = 'jdbc:mysql://mysql:3306/analytics',
    'table-name' = 'user_activity_uv',
    'username' = 'flink',
    'password' = 'flinkpw',
    'sink.buffer-flush.interval' = '1s'
);

-- 计算滑动窗口UV并写入MySQL
INSERT INTO user_activity_uv
SELECT 
    window_start,
    window_end,
    COUNT(DISTINCT user_id) AS uv
FROM TABLE(
    HOP(TABLE user_events, DESCRIPTOR(event_time), 
        INTERVAL '1' MINUTES, INTERVAL '10' MINUTES)
)
GROUP BY window_start, window_end;

 

 

DML

posted @ 2025-06-05 14:37  ---江北  阅读(28)  评论(0)    收藏  举报
TOP