|
|
@@ -678,6 +678,28 @@ PARTITIONED BY (dt STRING COMMENT '日期分区 yyyyMMdd')
|
|
|
STORED AS ORC;
|
|
|
```
|
|
|
|
|
|
+**raw 层 EXTERNAL 建表模板**(`manual/ddl/raw/trd/raw_trd_legacy_order_his_o_create.sql`):
|
|
|
+
|
|
|
+```sql
|
|
|
+-- ============================================================
|
|
|
+-- 表名:raw.raw_trd_legacy_order_his_o
|
|
|
+-- 业务含义:交易域-历史订单 CSV 导入(一次性 his)
|
|
|
+-- 分层:RAW(全字段 STRING;EXTERNAL 兜底,详见 20-数仓分层与建模.md §8.1)
|
|
|
+-- 负责人:tianyu.chu
|
|
|
+-- 创建日期:2026-xx-xx
|
|
|
+-- 状态:[待执行]
|
|
|
+-- ============================================================
|
|
|
+
|
|
|
+CREATE EXTERNAL TABLE IF NOT EXISTS raw.raw_trd_legacy_order_his_o (
|
|
|
+ order_id STRING COMMENT '订单ID(源端字面量)',
|
|
|
+ user_id STRING COMMENT '用户ID(源端字面量)',
|
|
|
+ amount STRING COMMENT '金额(源端字面量)',
|
|
|
+ order_time STRING COMMENT '下单时间(源端字面量)'
|
|
|
+) COMMENT '交易域-历史订单CSV导入(一次性,全STRING)'
|
|
|
+STORED AS ORC
|
|
|
+LOCATION '/user/hive/warehouse/raw.db/raw_trd_legacy_order_his_o/';
|
|
|
+```
|
|
|
+
|
|
|
**ALTER 文件模板**(`manual/ddl/20260520_dwd_trd_order_pay_add_refund.sql`):
|
|
|
|
|
|
```sql
|
|
|
@@ -788,11 +810,13 @@ raw 层的 `jobs/` 有两类主要任务,根据源数据形态选择:
|
|
|
3. 调用 SparkSQL 执行 `jobs/raw/{域}/{表}.sql`,文件内通过 `USING csv OPTIONS(...)` 临时视图解析 CSV,再 `INSERT OVERWRITE` 写入对应 raw 表
|
|
|
4. 清理 HDFS 暂存文件
|
|
|
|
|
|
-**CSV 导入任务定义模板**(`jobs/raw/trd/raw_trd_legacy_order_his_o.sql`,**CTAS 一次性导入**):
|
|
|
+**CSV 导入任务定义模板**(`jobs/raw/trd/raw_trd_legacy_order_his_o.sql`):
|
|
|
+
|
|
|
+DDL 先在 `manual/ddl/raw_trd_legacy_order_his_o.sql` 按 raw 层规范建好 `EXTERNAL TABLE`(全字段 STRING,契约详见 `20-数仓分层与建模.md` §8.1;DDL 模板见本文档 §9.1 raw 变体)。本脚本只负责"读 CSV → 写入 EXTERNAL 表的 LOCATION"。
|
|
|
|
|
|
```sql
|
|
|
-- ============================================================
|
|
|
--- 目标表:raw.raw_trd_legacy_order_his_o
|
|
|
+-- 目标表:raw.raw_trd_legacy_order_his_o(EXTERNAL,DDL 在 manual/ddl/ 预建)
|
|
|
-- 业务含义:交易域 - 历史订单 CSV 导入(一次性历史快照 his)
|
|
|
-- 源数据:本地路径 /data/uploads/legacy_orders/historical.csv
|
|
|
-- 编码 UTF-8 / 带表头 / 逗号分隔 / 双引号 quote / 字段内允许换行
|
|
|
@@ -801,7 +825,6 @@ raw 层的 `jobs/` 有两类主要任务,根据源数据形态选择:
|
|
|
-- 负责人:tianyu.chu
|
|
|
-- 创建日期:2026-xx-xx
|
|
|
-- 状态:[待执行]
|
|
|
--- 备注:CTAS 语法一次性建表 + 写入,无需在 manual/ddl/ 单独写 CREATE TABLE
|
|
|
-- ============================================================
|
|
|
|
|
|
-- csv-to-hdfs-starter 通过文件头注释读取这两个变量并完成 gzip+put 操作
|
|
|
@@ -822,14 +845,7 @@ OPTIONS (
|
|
|
inferSchema 'false'
|
|
|
);
|
|
|
|
|
|
--- CTAS:一次性建表 + 写入,全字段 STRING(Spark 默认从 v_stage 推断为 STRING)
|
|
|
--- 不需要预先在 manual/ddl/ 写 CREATE TABLE
|
|
|
-DROP TABLE IF EXISTS raw.raw_trd_legacy_order_his_o;
|
|
|
-
|
|
|
-CREATE TABLE raw.raw_trd_legacy_order_his_o
|
|
|
-USING ORC
|
|
|
-COMMENT '交易域-历史订单CSV导入(一次性,全STRING)'
|
|
|
-AS
|
|
|
+INSERT OVERWRITE TABLE raw.raw_trd_legacy_order_his_o
|
|
|
SELECT
|
|
|
order_id,
|
|
|
user_id,
|
|
|
@@ -839,20 +855,15 @@ FROM v_raw_trd_legacy_order_stage
|
|
|
;
|
|
|
```
|
|
|
|
|
|
-**CTAS vs INSERT OVERWRITE 何时用哪个**:
|
|
|
+**raw 层写入模式对照**:
|
|
|
|
|
|
-| 场景 | 推荐写法 | 是否需要 `manual/ddl/` 文件 |
|
|
|
+| 场景 | 写法 | `manual/ddl/` |
|
|
|
|---|---|---|
|
|
|
-| **一次性 CSV 导入**(历史回刷、单批 vendor 数据),表名 `raw_xxx_his_o` | `DROP TABLE + CREATE TABLE ... AS SELECT`,**不分区** | 否,CTAS 一步搞定 |
|
|
|
-| **每日重复的 CSV 导入**(daily file drop) | 在 `manual/ddl/` 先建分区表,每日 SQL 用 `INSERT OVERWRITE TABLE ... PARTITION (dt='${dt}')` | 是,需要 `manual/ddl/{表名}.sql` |
|
|
|
-| **结构化源库同步**(PG/MySQL 等) | DataX ini,`writeMode=truncate` 或分区覆盖 | 是,需要 `manual/ddl/{表名}.sql` |
|
|
|
-
|
|
|
-**`his` 表为什么不分区**:一次性导入永不追加,分区裁剪没有意义;CTAS 也不适合直接建分区表(每次都会 `DROP`,无法保留历史分区)。如果业务要求"按日期看一眼",下游 ods 建分区表,用 `INSERT OVERWRITE PARTITION (dt) ... DISTRIBUTE BY dt` 一次性把 raw → ods 切片即可(见 §9.3.1)。
|
|
|
+| **一次性 CSV 导入**(历史回刷、单批 vendor 数据),表名 `raw_xxx_his_o` | 预建 `EXTERNAL TABLE`(不分区),`INSERT OVERWRITE TABLE ...` | 需要 |
|
|
|
+| **每日重复的 CSV 导入**(daily file drop) | 预建分区 `EXTERNAL TABLE`,每日 `INSERT OVERWRITE TABLE ... PARTITION (dt='${dt}')` | 需要 |
|
|
|
+| **结构化源库同步**(PG/MySQL 等) | DataX ini,写入预建 `EXTERNAL TABLE`(`writeMode=truncate` 或分区覆盖) | 需要 |
|
|
|
|
|
|
-**为什么 CSV 一次性导入推荐 CTAS**:
|
|
|
-- 省掉单独写 `manual/ddl/{表名}.sql` 的步骤,减少维护点
|
|
|
-- 字段类型由 SELECT 列自动确定(CSV 全 STRING 场景下 Spark 默认推断为 STRING,符合 raw 层契约)
|
|
|
-- `DROP + CREATE` 配合 `IF EXISTS` 是幂等的,重跑安全
|
|
|
+**`his` 表为什么不分区**:一次性导入永不追加,分区裁剪没有意义。下游 ods 再按 `dt` 分区,用 `INSERT OVERWRITE PARTITION (dt) ... DISTRIBUTE BY dt` 一次性把 raw → ods 切片(见 §9.3.1)。
|
|
|
|
|
|
**为什么用 SQL 而不是 YAML 描述 CSV 任务**:
|
|
|
- 复用 `SparkSQL` 现有执行链,`bin/csv-to-hdfs-starter.py` 只需在 `bin/spark-sql-starter.py` 之外加一层 gzip+put+清理的薄壳,不需要单独的 YAML 渲染器
|