1. DELETE 是干什么的?
DELETE语句用于对目标表执行行级删除:
- 带 WHERE:删除满足条件的行
- 不带 WHERE:删除全表所有行(语义上等价“整表删除”,但不是 drop 表)
2. 重要限制(必读)
⚠️ 注意(官方强调)
1)DELETE目前只支持 Batch 模式
2)目标表 connector 必须实现SupportsRowLevelDelete,才能支持行级删除
3)如果对未实现该接口的表执行 DELETE,会抛异常
4)目前 Flink 官方维护的 connector还没有任何一个支持 DELETE
这段话决定了 DELETE 的现实处境:语法层支持,并不代表你用任何 connector 都能跑通。在生产中,你往往需要替代方案(第 7 节会给你)。
3. 语法速记
DELETEFROM[catalog_name.][db_name.]table_name[WHEREcondition]- 表名支持全限定名:
catalog.db.table WHERE可选;省略则删除全表数据
4. Java 执行机制:executeSql 会立刻提交一个 Flink Job
在 Java 中,DELETE通过TableEnvironment.executeSql()执行。
执行 DELETE 会立即提交一个 Flink 作业,并返回TableResult(与提交的作业关联)。
你可以把它理解为:Flink 不是“数据库里立刻删几行”,而是“提交一个批作业去完成删除”。
5. Java 实战示例:条件删除 + 全表删除
下面是你提供示例的“更清爽排版版”,保留关键语句与执行顺序:
EnvironmentSettingssettings=EnvironmentSettings.newInstance().inBatchMode().build();TableEnvironmenttEnv=TableEnvironment.create(settings);// 1) 注册 Orders 表tEnv.executeSql("CREATE TABLE Orders ("+" `user` STRING, "+" product STRING, "+" amount INT"+") WITH (...)");// 2) 插入数据tEnv.executeSql("INSERT INTO Orders VALUES "+"('Lili', 'Apple', 1), "+"('Jessica', 'Banana', 2), "+"('Mr.White', 'Chicken', 3)").await();// 3) 条件删除:删掉 user='Lili'tEnv.executeSql("DELETE FROM Orders WHERE `user` = 'Lili'").await();// 4) 全表删除:删空 OrderstEnv.executeSql("DELETE FROM Orders").await();✅ 小细节建议
字段名user建议继续用反引号包裹,避免关键字冲突。
6. 你最可能遇到的报错原因(以及怎么判断)
6.1 connector 不支持 row-level delete(最常见)
表现:执行DELETE直接抛异常,提示该表/connector 不支持行级删除能力。
根因:目标表 connector 没实现SupportsRowLevelDelete。
6.2 不是 Batch 模式
表现:在流模式下执行 DELETE,不被支持或语义不成立。
正确做法:确保运行在 batch(Java 示例里通过inBatchMode()已保证)。
7. 现实落地:官方 connector 目前不支持 DELETE,怎么办?
既然官方明确“目前没有内置 connector 支持 DELETE”,那生产怎么做?这里给你一组工程替代方案(写进博客会更有含金量):
方案 A:用 TRUNCATE 替代“全表 DELETE”
如果你的目标是清空整表(不是带 WHERE 的按条件删),优先考虑:
TRUNCATETABLEt;当然同样要看 connector 是否支持 truncate(是否实现对应能力接口)。
方案 B:批处理重算 + 覆盖写(离线数仓最常用)
如果你想“删除某些行”,在离线场景里更通用的做法是:
- 重新计算“保留的数据集”(相当于
SELECT ... WHERE NOT (...)) - 写到新表/新分区
- 通过交换表名/覆盖分区完成“逻辑删除效果”
方案 C:主键 Upsert 覆盖(把删除转成标记/状态)
对于更偏在线或下游支持主键的系统,可以把“删除”改成:
- 写入一条带
is_deleted=true的记录(软删除) - 或写入 tombstone(具体取决于 sink 能力与业务模型)
方案 D:实现/使用支持 row-level delete 的第三方 connector
如果你确实需要 SQL 级 DELETE 语义,那就只能:
- 使用具备该能力的外部 connector
- 或自研 connector 来实现
SupportsRowLevelDelete
8. 总结
DELETE用于对目标表执行行级删除:可带WHERE,也可删空整表当前仅支持 Batch 模式
依赖目标表 connector 实现
SupportsRowLevelDelete,否则直接抛异常现阶段由于内置 connector 不支持,生产中更常见的是:
- 全表清空用
TRUNCATE(看 connector 能力) - 条件删除用“重算覆盖/软删除/upsert/外部能力”替代
- 全表清空用