|
|
@@ -24,10 +24,12 @@ poyee-data-warehouse/ # 项目根目录(仓库名 = 部署名)
|
|
|
│ ├── ads/ # 应用层计算 SQL + 导出 ini
|
|
|
│ └── archive/ # 已执行完的历史脚本归档
|
|
|
├── manual/ # 一次性脚本(禁止接入定时调度)
|
|
|
-│ ├── ddl/ # 所有 DDL(初始 CREATE + 后续 ALTER),唯一来源
|
|
|
+│ ├── ddl/ # 所有 DDL(初始 CREATE + 后续 ALTER),唯一来源;按 {layer}/{domain}/ 分子目录
|
|
|
│ ├── backfill/ # 历史数据回刷
|
|
|
│ ├── fix/ # 线上脏数据订正(必须带工单号)
|
|
|
-│ └── adhoc/ # 临时取数 / 排查
|
|
|
+│ ├── adhoc/ # 临时取数 / 排查
|
|
|
+│ ├── imports/{yyyymmdd}/ # 一次性入仓(硬盘、历史 dump、外部 CSV),按执行日期归档
|
|
|
+│ └── exports/{yyyymmdd}/ # 一次性出仓任务,按执行日期归档
|
|
|
├── dw_base/ # 通用库层
|
|
|
│ ├── __init__.py # 全局初始化
|
|
|
│ ├── common/ # 常量、容器
|
|
|
@@ -678,10 +680,12 @@ bin/datax-multiple-hive-job-starter.sh -gcd jobs/raw/trd -start-date 20260415 -e
|
|
|
|
|
|
| 目录 | 用途 |
|
|
|
|------|------|
|
|
|
-| `manual/ddl/` | 一次性 DDL:加列、改分区、补建表 |
|
|
|
+| `manual/ddl/` | 所有 DDL(初始 CREATE + 后续 ALTER),唯一来源;内部按 `{layer}/{domain}/` 分子目录 |
|
|
|
| `manual/backfill/` | 历史数据回刷(跨日期重算) |
|
|
|
| `manual/fix/` | 线上脏数据订正,**必须附工单号** |
|
|
|
| `manual/adhoc/` | 临时取数、问题排查 |
|
|
|
+| `manual/imports/{yyyymmdd}/` | 一次性入仓任务(离线硬盘、历史 dump、外部 CSV 等),按执行日期归档 |
|
|
|
+| `manual/exports/{yyyymmdd}/` | 一次性出仓任务,按执行日期归档 |
|
|
|
| `manual/archive/` | 执行完毕的历史脚本归档,保留审计痕迹 |
|
|
|
|
|
|
**命名规则**:`{yyyymmdd}_{层}_{域}_{简述}.sql`,例如 `20260414_dwd_trd_add_refund_col.sql`
|
|
|
@@ -710,26 +714,40 @@ bin/datax-multiple-hive-job-starter.sh -gcd jobs/raw/trd -start-date 20260415 -e
|
|
|
|
|
|
|
|
|
一张表的完整生命周期涉及:
|
|
|
-- `manual/ddl/{表名}_create.sql` —— 首次建表,永久保留
|
|
|
-- 若干 `manual/ddl/{表名}_{yyyymmdd}_{描述}_change.sql` —— 之后每次 ALTER,独立文件
|
|
|
-- `jobs/{layer}/{domain}/{表名}.sql` —— 每日调度的计算 SQL(不含建表)
|
|
|
+- `manual/ddl/{layer}/{domain}/{表名}_create.sql` —— 首次建表,永久保留
|
|
|
+- 若干 `manual/ddl/{layer}/{domain}/{表名}_{yyyymmdd}_{描述}_change.sql` —— 之后每次 ALTER,独立文件
|
|
|
+- `jobs/{layer}/{domain}/{表名}.sql` 或 `jobs/{layer}/{domain}/{表名}/{表名}-{NN}-{描述}.sql` —— 每日调度的计算 SQL(不含建表),详见 §9.2
|
|
|
|
|
|
### 9.1 `manual/ddl/` —— DDL 唯一来源
|
|
|
|
|
|
-**目录组织**:扁平存放,不再按 `{layer}/{domain}/` 分子目录 —— 因为每张表只在 `manual/ddl/` 出现一次(外加若干 ALTER 文件),扁平就够用。`grep dwd_trd_ manual/ddl/` 一行命令就能列出某表的所有 DDL 历史。
|
|
|
+**目录组织**:按 `{layer}/{domain}/` 分子目录。layer 代码取自 `21-命名规范.md` §3.1(`raw`/`ods`/`dim`/`dwd`/`dws`/`tdm`/`ads`),domain 代码取自 §3.2(`trd`/`usr`/`prd`/`shp`/`pub`)。每张目标表的首次建表 + 所有 ALTER 都落在这个子目录里,便于一眼看清某层某域的表清单。
|
|
|
|
|
|
```
|
|
|
manual/ddl/
|
|
|
-├── raw_trd_order_pay_inc_d.sql # 首次建表(永久保留)
|
|
|
-├── ods_trd_order_pay_inc_d.sql
|
|
|
-├── dwd_trd_order_pay_inc_d.sql
|
|
|
-├── ads_trd_gmv_d.sql
|
|
|
-├── 20260520_dwd_trd_order_pay_add_refund.sql # ALTER(执行后归档)
|
|
|
-├── 20260612_raw_trd_legacy_order_change_partition.sql
|
|
|
+├── raw/
|
|
|
+│ └── trd/
|
|
|
+│ ├── raw_trd_order_pay_inc_d_create.sql # 首次建表(永久保留)
|
|
|
+│ └── 20260612_raw_trd_legacy_order_change_partition.sql
|
|
|
+├── ods/
|
|
|
+│ └── trd/
|
|
|
+│ └── ods_trd_order_pay_inc_d_create.sql
|
|
|
+├── dwd/
|
|
|
+│ └── trd/
|
|
|
+│ ├── dwd_trd_order_pay_inc_d_create.sql
|
|
|
+│ └── 20260520_dwd_trd_order_pay_add_refund.sql # ALTER(独立文件,不改原文件)
|
|
|
+├── ads/
|
|
|
+│ └── trd/
|
|
|
+│ └── ads_trd_gmv_d_create.sql
|
|
|
+├── tmp/ # 单目标加速中间表 DDL(见 §9.2)
|
|
|
+│ └── dwd_trd_order_pay/
|
|
|
+│ ├── tmp_dwd_trd_order_pay_01_create.sql
|
|
|
+│ └── tmp_dwd_trd_order_pay_02_create.sql
|
|
|
└── archive/
|
|
|
└── 20260301_old_alter.sql # 已归档
|
|
|
```
|
|
|
|
|
|
+**按 `grep` 的友好度**:`grep -r "CREATE TABLE.*dwd_trd_order_pay_inc_d" manual/ddl/` 仍能直接命中;分子目录带来的额外索引成本小于"一眼看到分层分域"的收益。
|
|
|
+
|
|
|
**首次建表 DDL 文件模板**(`manual/ddl/dwd_trd_order_pay_inc_d.sql`):
|
|
|
|
|
|
```sql
|
|
|
@@ -780,15 +798,39 @@ ADD COLUMNS (
|
|
|
|
|
|
### 9.2 `jobs/` 层 —— 每日调度的计算 SQL
|
|
|
|
|
|
-**文件粒度**:一个 `.sql` 对应一张目标表。只写 `INSERT OVERWRITE`,**不写 CREATE TABLE**(表由 `manual/ddl/` 保证已存在)。
|
|
|
+**文件粒度:一张目标表对应一套 SQL 文件**,按复杂度两档:
|
|
|
+
|
|
|
+- **简单表** — `jobs/{layer}/{domain}/{表名}.sql` 一个文件顶到底(单次 `INSERT OVERWRITE`,可带 `WITH` CTE)
|
|
|
+- **多步表** — `jobs/{layer}/{domain}/{表名}/{表名}-{NN}-{描述}.sql`,序号三位,`99` 固定留给最终 `INSERT OVERWRITE` 目标表那一步。DS 工作流对应 N 个 task 节点按序号链式依赖
|
|
|
+
|
|
|
+所有 `.sql` 只写 `INSERT OVERWRITE` / `INSERT INTO`,**不写 CREATE TABLE**(表由 `manual/ddl/` 保证已存在)。
|
|
|
|
|
|
```
|
|
|
jobs/dwd/trd/
|
|
|
-├── dwd_trd_order_pay_inc_d.sql
|
|
|
-├── dwd_trd_order_refund_inc_d.sql
|
|
|
-└── dwd_trd_shop_gmv_agg_ful_d.sql
|
|
|
+├── dwd_trd_order_refund_inc_d.sql # 简单表,单文件
|
|
|
+├── dwd_trd_shop_gmv_agg_ful_d.sql
|
|
|
+└── dwd_trd_order_pay_inc_d/ # 多步表,目标表名同名子目录
|
|
|
+ ├── dwd_trd_order_pay_inc_d-01-build_tmp_pay_base.sql
|
|
|
+ ├── dwd_trd_order_pay_inc_d-02-build_tmp_refund_agg.sql
|
|
|
+ └── dwd_trd_order_pay_inc_d-99-insert_target.sql
|
|
|
```
|
|
|
|
|
|
+**什么时候从简单表升级到多步表:**
|
|
|
+
|
|
|
+| 触发条件 | 处理 |
|
|
|
+|---------|------|
|
|
|
+| 单 SQL shuffle 过大(单作业耗时 > 30 min 且 shuffle read > 100GB) | 拆分中间结果物化为 tmp 表 |
|
|
|
+| 同一块 CTE 在多个 WITH 节里重复扫描 | 物化后 cache 复用 |
|
|
|
+| 复杂业务逻辑,读多源后多轮 join,需要中间落盘便于 debug / 回溯 | 拆分单步 |
|
|
|
+| 中间结果需要被**多个目标表**复用 | **不用 tmp**,升层为 dwd/dws 独立表 |
|
|
|
+
|
|
|
+**中间表两类,严格区分:**
|
|
|
+
|
|
|
+1. **单目标加速中间表(tmp)** — 只服务本目标表,命名 `tmp_{目标表名}_{NN}`,DDL 收到 `manual/ddl/tmp/{目标表名}/` 子目录。生命周期跟随本次任务,每次 `INSERT OVERWRITE` 覆盖或 drop+recreate,不留历史
|
|
|
+2. **可复用中间结果** — 被 ≥2 个目标表引用,**升层为独立 dwd/dws 表**,按正常五段式命名,DDL 单独登记。**不允许用 tmp 前缀**
|
|
|
+
|
|
|
+**从单文件升级到子目录的操作步骤**:删掉原单文件,建子目录、拆 SQL、DS 工作流拆 task 节点;`manual/ddl/tmp/{目标表名}/` 同步补齐 tmp 表 DDL。一次性改完,避免半新半旧。
|
|
|
+
|
|
|
**计算 SQL 文件模板**:
|
|
|
```sql
|
|
|
-- ============================================================
|
|
|
@@ -822,7 +864,7 @@ WHERE o.dt = '${dt}'
|
|
|
;
|
|
|
```
|
|
|
|
|
|
-对需要多步 CTE 或中间结果的复杂加工,用 `WITH` + 最终 `INSERT OVERWRITE` 写在同一文件内,不拆分多文件。
|
|
|
+**WITH / CTE 还是拆文件**:轻量中间结果用 `WITH` 内联(不物化,本质还是单 SQL);重量中间结果需要物化为 tmp 表时才升级到"多步表子目录"(见本节上方触发条件表)。不要盲目把 CTE 都拆成 tmp —— shuffle 不大、不复用的 CTE 留在 `WITH` 里反而更清爽。
|
|
|
|
|
|
### 9.3 raw 层(采集任务)
|
|
|
|
|
|
@@ -971,11 +1013,14 @@ jobs/ads/trd/
|
|
|
|
|
|
| 目录 | 文件后缀 | 文件名规则 | 说明 |
|
|
|
|---|---|---|---|
|
|
|
-| `manual/ddl/` | `.sql` | `{目标表名}.sql`(首次) 或 `{yyyymmdd}_{表名}_{change}.sql`(ALTER) | DDL 唯一来源;首次建表用 `CREATE TABLE IF NOT EXISTS`,后续 ALTER 带日期前缀,执行后归档 |
|
|
|
+| `manual/ddl/{layer}/{domain}/` | `.sql` | `{表名}_create.sql`(首次) 或 `{yyyymmdd}_{表名}_{change}.sql`(ALTER) | DDL 唯一来源;首次建表用 `CREATE TABLE IF NOT EXISTS`,后续 ALTER 带日期前缀 |
|
|
|
+| `manual/ddl/tmp/{目标表名}/` | `.sql` | `tmp_{目标表名}_{NN}_create.sql` | 多步表的单目标加速中间表 DDL |
|
|
|
| `jobs/raw/{domain}/` | `.ini`(DataX)或 `.sql`(CSV 导入) | `{目标表名}.ini` 或 `{目标表名}.sql` | DataX 采集或 CSV 导入任务定义 |
|
|
|
-| `jobs/{ods\|dwd\|dws\|tdm}/{domain}/` | `.sql` | `{目标表名}.sql` | 每日 `INSERT OVERWRITE` 计算 |
|
|
|
-| `jobs/ads/{domain}/` | `.sql` + `.ini` | `{ads 表名}.sql` + `{ads 表名}__{db_type}_{instance}.ini` | 产出 + 导出;同一张 ads 表扇出多下游时各一份 ini(见 `21-命名规范.md` §3.9) |
|
|
|
+| `jobs/{ods\|dwd\|dws\|tdm}/{domain}/` | `.sql` | **简单表**:`{目标表名}.sql`;**多步表**:子目录 `{目标表名}/{目标表名}-{NN}-{描述}.sql`(`99` 为最终 insert) | 每日 `INSERT OVERWRITE` 计算,详见 §9.2 |
|
|
|
+| `jobs/ads/{domain}/` | `.sql` + `.ini` | **简单表**:`{ads 表名}.sql` + `{ads 表名}__{db_type}_{instance}.ini`;**多步**:`{ads 表名}/{ads 表名}-{NN}-{描述}.sql` + 同级目录放 ini | 产出 + 导出;同一张 ads 表扇出多下游时各一份 ini(见 `21-命名规范.md` §3.9) |
|
|
|
| `manual/backfill/` | `.sql` | `{yyyymmdd}_{表名}_history.sql` | 一次性历史回刷脚本 |
|
|
|
+| `manual/imports/{yyyymmdd}/` | `.ini` / `.sql` | `{任务描述}.ini` 或 `.sql` | 一次性入仓任务(离线硬盘、历史 dump、外部 CSV 等),按执行日期归档 |
|
|
|
+| `manual/exports/{yyyymmdd}/` | `.ini` | `{任务描述}.ini` | 一次性出仓任务,按执行日期归档 |
|
|
|
|
|
|
### 9.6 表结构变更流程(migration 模式)
|
|
|
|