1. 什么是 Table ID?为什么需要它?
定义 :当连接外部系统(数据库/消息队列)时,需要将作业内的逻辑表与外部系统的"存储对象"(表、主题等)建立一一映射关系,这个映射键 就是 Table ID。
价值:
- 让整库同步 、多表路由 、分表并表有据可依;
- 把"名字语义"从具体连接器里抽象出来,跨系统更稳定;
- 为 Schema 演进 、权限白名单 、数据分域等治理能力提供锚点。
2. 跨系统对照:同一把尺子量不同世界
Table ID 使用一个三元抽象:
(namespace, schemaName, tableName)
不同系统对应的层级不同(不足三段时按实际存在的层级取值),常见映射如下:
| 数据系统 | Table ID 由哪些部分构成 | 字符串示例 |
|---|---|---|
| Oracle / PostgreSQL | database, schema, table | mydb.default.orders |
| MySQL / Doris / StarRocks | database, table | mydb.orders |
| Kafka | topic | orders |
说明:三元只是统一抽象 。例如 MySQL 没有 schema 概念,就使用
database.table;Kafka 只有 topic。
3. YAML 怎么写:整库、白名单、正则与转义
3.1 整库同步(常用)
yaml
source:
type: mysql
tables: 'app_db\.\*' # 正则匹配整库,点号要写成 \.;建议整体用引号包起来
3.2 多表白名单
yaml
source:
type: mysql
tables: 'app_db\.(orders|shipments|products)'
3.3 PostgreSQL / Oracle(含 schema 的三段式)
yaml
source:
type: postgresql
tables: 'mydb\.public\.orders'
3.4 Kafka(topic)
yaml
source:
type: kafka
topics: 'orders' # 或正则:'orders_.*'
小贴士
- 写正则时点号是元字符 ,要用
\.表示"字面点"。- 在 YAML 中用单引号包住模式字符串,避免转义层级混乱。
- 大小写是否敏感取决于外部系统(PostgreSQL 不加引号默认小写;MySQL 还可能受文件系统影响),尽量与真实元数据大小写一致。
4. Route + Transform:Table ID 的组合技
Route(路由):用 Table ID 做选择器,把源端对象改名、换库或合并到目标库表。
Transform(转换):在落地前对字段做投影/改名/类型修正/派生,输出"治理后"的一致形态。
4.1 跨库改名(迁移)
yaml
route:
- source-table: 'app_db\.orders'
sink-table: 'ods_db.ods_orders'
- source-table: 'app_db\.shipments'
sink-table: 'ods_db.ods_shipments'
4.2 分表并表(正则聚合)
yaml
route:
- source-table: 'app_db\.order_.*' # order_01 / order_02 / ...
sink-table: 'ods_db.ods_orders'
⚠️ 当前常见实现不支持 "不同分表中存在相同主键记录"的并表冲突场景。若确有此类数据,需在上游或 Transform 层先做去重/裁剪策略。
5. 与 Schema 演进、Exactly-Once 的关系
- Schema 演进(DDL 跟随) :Table ID 是"变更的作用域"。当源端
ADD COLUMN/MODIFY时,配合下游(如 Doris/StarRocks 的轻量级变更)可自动/半自动对齐。 - Exactly-Once:端到端一致性离不开主键/唯一键等约束。Route 合并后务必确认目标表的主键策略,确保 Upsert/幂等写入的语义成立。
6. 端到端示例:MySQL → StarRocks(整库 + 演进友好)
yaml
source:
type: mysql
hostname: localhost
port: 3306
username: root
password: 123456
tables: 'app_db\.\*'
server-id: 5400-5404
server-time-zone: UTC
sink:
type: starrocks
jdbc-url: 'jdbc:mysql://127.0.0.1:9030'
load-url: '127.0.0.1:8030' # 部分镜像是 8080;请与实际 FE HTTP 一致
username: root
password: ""
table.create.properties.replication_num: 1
# 若需要 upsert 语义,可选用主键模型(按版本能力调整):
# table.create.properties.duplicate_key: false
# table.create.properties.primary_key: "id"
pipeline:
name: Sync MySQL Database to StarRocks
parallelism: 2
- 将来新增
orders.amount、或将shipments.city改长,下游可随配置自动对齐; - 需要迁移/改名时,加一段
route即可,不动上游增量流程。
7. 上线前自检清单(Checklist)
-
表选择是否准确
- 整库:
'db\.\*'是否书写正确、加了引号? - 白名单:正则是否只覆盖期望表?是否需要排除测试表?
- 整库:
-
大小写与引号
- 与真实元数据大小写一致;PostgreSQL/Oracle 的 DDL 是否用双引号约束大小写?
-
主键/唯一键策略
- 目标端是否具备 upsert/幂等所需的约束?分表并表后是否会产生冲突?
-
Schema 演进策略
- 新增列默认值?类型扩/收窄是否兼容?是否需要灰度(新增新列 → 回填 → 下线旧列)?
-
时区
server-time-zone已显式设置?时间字段无偏移风险?
-
权限与最小化原则
- 源端账号仅有必要权限(如 REPLICATION、SELECT)?目标端仅开放指定库表?
-
Savepoint / 回滚
- 重要变更前是否打了 Savepoint?失败可否平滑回退?
8. 常见坑位与快速定位
- 正则转义漏写 :
app_db.*(错)会把.当成任意字符,应写成app_db\.\*(对),并用引号包起来。 - FE HTTP 端口不一致 (StarRocks/Doris):实际是 8030 还是 8080?请与
load-url、浏览器访问保持一致。 - server-id 冲突(MySQL):报 "server-id in use";换一个不冲突的区间即可。
- 大小写陷阱(PostgreSQL):未加引号的标识符会强制小写,导致与 Table ID 不一致。
- 并表主键冲突:多源分表写同一目标表时,若主键重复,将出现幂等语义不确定或被覆盖。
9. 结语
Table ID = 作业内"指向外部对象"的稳定锚点 。
有了它,整库同步、路由改名、分表并表、Schema 演进都能以声明式方式持续演化。把"如何指认一张表"这件小事处理好,才能让后续的一致性、治理与运维都立得住。