Forráskód Böngészése

docs(kb/23): 反馈 1 期落地 tag_type + tag_code 命名 + _d/_o 分表(链 kb/33 详表)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tianyu.chu 2 napja
szülő
commit
b031b9b8e2
2 módosított fájl, 27 hozzáadás és 12 törlés
  1. 26 12
      kb/23-标签体系.md
  2. 1 0
      kb/92-重构进度.md

+ 26 - 12
kb/23-标签体系.md

@@ -12,11 +12,10 @@ DWD / DWS(事实 + 维度)
         |
         v
   +---------------------------------------------+
-  |  TDM 标签明细长表(EAV)                      |
-  |  tdm_usr_tag_ful_d                           |
-  |  tdm_prd_tag_ful_d                           |
-  |  tdm_shp_tag_ful_d                           |
-  |  所有标签纵向存放,灵活扩展,不改表结构         |
+  |  TDM 标签明细长表(EAV)                          |
+  |  tdm_{usr|prd|shp}_tag_d  日更长表(_d 后缀)      |
+  |  tdm_{usr|prd|shp}_tag_o  往年凝固(_o 后缀)      |
+  |  所有标签纵向存放,灵活扩展,不改表结构             |
   +--------------+------------------------------+
                  | pivot 高频核心标签
                  v
@@ -39,6 +38,7 @@ DWD / DWS(事实 + 维度)
 
 **设计原则**:
 - 按**实体类型**分表(用户/商品/商家),不按标签主题拆表
+- 长表分 `_d` 日更(属性 snap + 当年累计 + 滚动窗口)/ `_o` 凝固(往年总额,按 `dt='{yyyy}1231'` 单表多分区,业界 Kimball 周期快照事实表标准);写入策略不同必须分表(详见 kb/33 §1.3)
 - 长表负责**全量明细存储**,宽表负责**高频服务**,人群包负责**圈选计算**
 - 前期只用 Hive 做离线标签计算,不引入额外组件
 
@@ -48,11 +48,12 @@ DWD / DWS(事实 + 维度)
 
 **表清单**:
 
-| 表名 | 实体 | 更新策略 |
-|------|------|---------|
-| `tdm_usr_tag_ful_d` | 用户 | 全量重刷,日 |
-| `tdm_prd_tag_ful_d` | 商品 | 全量重刷,日 |
-| `tdm_shp_tag_ful_d` | 商家 | 全量重刷,日 |
+| 表名 | 实体 | 更新策略 | scope |
+|------|------|---------|---|
+| `tdm_usr_tag_d` | 用户 | 日更全量重刷 dt='${dt}',每天 INSERT OVERWRITE 单分区 | ✅ 1 期落地(kb/33 §2)|
+| `tdm_usr_tag_o` | 用户 | 往年总额凝固 dt='{yyyy}1231',单表多分区 insert-only | ✅ 1 期落地(kb/33 §3)|
+| `tdm_prd_tag_d` / `tdm_prd_tag_o` | 商品 | 同 schema | ⏸ 2 期 scope |
+| `tdm_shp_tag_d` / `tdm_shp_tag_o` | 商家 | 同 schema | ⏸ 2 期 scope |
 
 **典型字段结构**:
 
@@ -61,7 +62,7 @@ DWD / DWS(事实 + 维度)
 | `entity_id` | BIGINT | 实体 ID(user_id / product_id / shop_id) |
 | `tag_code` | STRING | 标签编码(全局唯一,如 `usr_gender`、`usr_pref_sport`) |
 | `tag_value` | STRING | 标签值(统一 STRING,下游按需转型) |
-| `tag_type` | STRING | 标签类型(`categorical` / `numeric` / `boolean` / `json`) |
+| `tag_type` | STRING | 标签类型(`attr` 属性 / `stat` 统计 / `rule` 规则;预留 `algo` 算法标签)|
 | `confidence` | DECIMAL(5,4) | 置信度(0~1,规则标签填 1.0,模型标签填模型输出) |
 | `etl_time` | TIMESTAMP | ETL 写入时间 |
 | `dt` | STRING | 分区日期 |
@@ -71,8 +72,19 @@ DWD / DWS(事实 + 维度)
 - 所有标签统一口径管理,便于建设标签字典元数据
 - 支持按 `tag_code` 灵活查询任意标签组合
 
+**1 期落地标签清单**(用户域共 103 个 tag_code,详见 kb/33 §2.4 + §3.4):
+
+| 表 | 类别 | tag_code 数 | 内容 |
+|---|---|---|---|
+| `tdm_usr_tag_d` | attr 属性 | 7 | usr_level / usr_is_cert / usr_sex / usr_city / usr_register_time / usr_birth_month / usr_generation |
+| `tdm_usr_tag_d` | stat 偏好 30d | 32 | 16 品类 × {amt, cnt},`usr_pref_trade_{category}_{amt,cnt}_30d` |
+| `tdm_usr_tag_d` | stat 偏好 y{当年} | 32 | 16 品类 × {amt, cnt},`usr_pref_trade_{category}_{amt,cnt}_y{当年}`(1 期当年=2026)|
+| `tdm_usr_tag_o` | stat 偏好 y{往年} | 32 / 凝固年 | 16 品类 × {amt, cnt},`usr_pref_trade_{category}_{amt,cnt}_y{往年}`(1 期凝固 y2025)|
+
 ## 3. 核心标签宽表
 
+> **1 期 scope 外**:1 期标签未完善(kb/33 §7),等长表稳定 + 高频标签固定后再启动;过早做宽表会引出 schema 频繁 ALTER + 重刷历史。下面是设计预案。
+
 从长表 pivot 高频、核心标签为列,供下游 ADS 和 BI 直接 JOIN,避免每次都对长表做条件聚合。
 
 **表清单**:
@@ -124,6 +136,8 @@ GROUP BY entity_id
 
 ## 4. 人群包
 
+> **1 期 scope 外**:1 期不做圈选(kb/33 §7),等业务侧有实时圈选诉求后再启动。下面是设计预案。
+
 以圈选规则为主键,存储实体 ID 集合,支持人群圈选和二次计算(交集、并集、差集)。
 
 **阶段 1 为单表设计**:所有人群包存入一张表 `tdm_usr_crowd_ful_d`,每行一个人群(`crowd_code` 区分)。阶段 2+ 存储格式从 `ARRAY<BIGINT>` 升级为 `BINARY`(bitmap),但表结构不变。详见 &sect;6 演进路线。
@@ -134,7 +148,7 @@ GROUP BY entity_id
 
 | 字段 | 说明 |
 |------|------|
-| `tag_code` | 全局唯一编码,格式 `{实体}_{标签名}`(如 `usr_gender`、`prd_price_band`) |
+| `tag_code` | 全局唯一编码,详细命名约定见 kb/33 §4。属性 `usr_{属性名}`(如 `usr_sex` / `usr_city`);偏好 `usr_pref_{主题}_{category}_{metric}_{window}`(如 `usr_pref_trade_basketball_amt_30d`)|
 | `tag_name` | 中文名称 |
 | `entity_type` | `usr` / `prd` / `shp` |
 | `tag_type` | `categorical` / `numeric` / `boolean` / `json` |

+ 1 - 0
kb/92-重构进度.md

@@ -183,6 +183,7 @@
 | 2026-05-09 | **kb/27 discount→merchant_discount + discount_amount 加派生 + DWD 调度双前置**:(a) §2.5 派生映射 `discount` 加 merchant_ 前缀(`discount_amt_cny` → `merchant_discount_amt_cny`):业务库字段 `discount` 字面"折扣"未体现"商家方"语义,加全名 merchant_ 前缀突出商家维度(不抄业务侧 SQL 别名 mer_coupon,因公司"折扣 vs 券"是否同义未确认,待业务侧定)。(b) `discount_amount` 从"待问是否派生"拍板按通式派生,临时命名 `discount_amount_amt_cny ❓`,与 merchant_discount 语义区别 + 最终命名仍待业务答复。(c) §1.4 加调度依赖行:DS DEPENDENT 同 dt ODS + 同 dt DIM ful_d 双前置(按 Kimball 维度退化原则,DWD 必依赖 DIM 同分区跑完)。 | — |
 | 2026-05-10 | **kb/93 加 ADR-08 DIM ful_d 跑批:业界主流模式 B + 字段 CASE WHEN 整组判断**:本项目第一张 dim 表 dim_usr_user_ful_d 落地(commits 5a28815 / 305a63b / ad7925a / 5d09add / 7c6cb5e)后沉淀通用范式:(a) init 扫 ods 历史 dt<${dt} + ROW_NUMBER 取每 pk 最新版本落 dim.${pdt} 首日分区;(b) sche 今日 ods 增量 + 昨日 dim 基线 + UNION ALL(today_rebuilt 重 join + unchanged 直接保留);(c) 字段合并按"组"用 CASE WHEN(如 base 整组按 bu.id IS NOT NULL,cert 整组按 ci.user_id IS NOT NULL),不用字段级 COALESCE 避免业务库主动置 NULL 场景下昨日值错误兜底;(d) init 与 sche 同日上线 init 灌 ${pdt} + sche 写 ${dt} 链路打通。否决方案:每日全量重算(扫描成本高)/ FULL JOIN + COALESCE(NULL 不安全)/ 扫 ods 历史 + broadcast filter(IO 成本高)/ MERGE INTO(Spark 2.4 不支持,迁 Spark 3+ / Hudi / Iceberg / Delta Lake 后再用)。 | — |
 | 2026-05-10 | **dwd_pay sche 改回算近 2 日 + 删 order_type='group' 过滤**:(a) 删 init / sche 两处 `order_type='group'`:dwd_pay 是数仓支付明细不限定订单类型,原 SQL 把 temp.sql 业务侧"拼团 GMV"分析的 `order_type='group'` 限定误搬入 dwd 入仓 SQL。(b) sche 写入策略从"单分区 dt=T-1 不回算"改为"回算近 2 日(dt IN ${dt}/${pdt})":原"不回算"基于"业务库 update_time 与 payment_success_time 同步刷新 OLTP 契约"假设;用户拍板"后端不可信",按业界主流 N=2 兜底跨零点漂移(业务时间 T-1 但 update_time 漂到 T 的事件,T+1 跑批时通过扫 ods.dt=T 兜回)。INSERT OVERWRITE PARTITION (dt) 动态分区只覆盖 SELECT 出现的 dt(kb/26 §8 项目默认 DYNAMIC mode)。(c) kb/27 §1.4 写入策略段同步更新(原"不回算"改"回算近 2 日 N=2 业界主流")。本次反复经过:5/9 信契约不回算 → 5/10 编漂移场景反悔 → 复盘 sessions 5/9 T8-T10 发现"自破契约"违反共识 → 用户重新拍板"后端不可信"接受回算 → 业界范围 N=2/3 拍 N=2。 | — |
+| 2026-05-11 | **kb/23 反馈 1 期落地:tag_type + tag_code 命名 + _d/_o 分表 + 103 个 tag_code 清单**:把 kb/33 落地内容反向同步到标签体系总览。改动点:(a) §1 架构 ASCII 长表块加 _d/_o 双后缀 + 设计原则加一条"长表分 _d 日更 / _o 凝固,写入策略不同必须分表(链 kb/33 §1.3)";(b) §2 表清单从 3 个统一 `_ful_d` 改为 4 行(用户 _d/_o ✅ 1 期落地 + 商品 / 商家 _d/_o ⏸ 2 期 scope);(c) §2 字段表 tag_type 枚举从 `categorical/numeric/boolean/json` 改 `attr/stat/rule`(预留 algo);(d) §2 末尾加"1 期落地标签清单"4 行表(attr 7 + 30d 32 + y{当年} 32 + y{往年}/凝固年 32 = 103 tag_code,详见 kb/33 §2.4 + §3.4);(e) §3 / §4 段首加"1 期 scope 外"标注(宽表 + 人群包 2 期再做);(f) §5 标签字典 tag_code 描述补 kb/33 §4 详细命名约定(属性 + 偏好两类模板)。不动 §6 演进路线(保留长期规划)。 | — |
 | 2026-05-11 | **kb/33 §3 + §5 改写:tdm_usr_tag_o 单表多 dt 分区代替每年一张表**:按 Kimball 周期快照事实表标准(单表 + insert-only 时间分区)+ 阿里 OneData 周期快照事实表范式 + EAV schema 永久稳定 + 1 期数据量级(300 万行 / 凝固年)远低于 sharding 阈值,原方案 A(每年一张 `tdm_usr_tag_y{yyyy}_o`)改方案 B(单表 `tdm_usr_tag_o`,按凝固年 `dt='{yyyy}1231'` 分区)。§3 标题 / 表名 / dt 锚点 / SQL 文件命名(`{date}_tdm_usr_tag_o_y{yyyy}.sql`)改写;§5 跨年扩张规则改为"落新 dt 分区"而非"新建表"。下游查询从 UNION 多表改为 `WHERE dt IN (...)` 单表多分区。README 索引描述层无变化。 | — |
 | 2026-05-11 | **kb/33-tdm建模.md 新建**:1 期用户标签 EAV 长表建模(属性 7 + 偏好 16 品类 × 4 窗口 = 64 共 71 个 tag_code)。设计要点:(a) 严守 kb/23 §2 EAV 7 字段不扩(entity_id / tag_code / tag_value / tag_type / confidence / etl_time / dt),新增维度组合只动 tag_code 命名不 ALTER 表;(b) tag_type 枚举 `attr / stat / rule`,预留 `algo` 给将来机器学习标签;(c) 按更新周期拆 `_d` 日更(属性 snap + 30d 滚动 + y{当年} 当年累计)/ `_o` 一次性凝固(y{往年} 总额,跨年 1-1 新建)两类表,业界 OneData / 字节做法;(d) tag_code 命名 `usr_{属性名}` / `usr_pref_{主题}_{category}_{metric}_{window}`,所有维度 encode 到 tag_code 字段;(e) tdm_usr_tag_d 来源 dim_usr_user_ful_d(属性)+ dws_usr_user_trade_1d(偏好);tdm_usr_tag_y2025_o 一次性聚合 dws_1d [20250101, 20251231];(f) 7 属性细节口径用合理默认(usr_level = member_level / usr_sex = sex_cert / usr_city = cert_city / usr_register_time = yyyyMMdd / usr_birth_month = yyyyMM / usr_generation = 10 年切片中文 N 后 / usr_is_cert = 布尔),待业务侧回头校准(EAV 收益);(g) 跨年扩张规则:每年 1-1 凝固上年累计为新 _o 表 + _d 表移除 y{上年} 新增 y{当年} tag_code。1 期 scope 外:宽表 / 人群包 / 商品店铺标签 / algo 类标签。README §2x 数仓建模索引加 kb/33 行。 | — |
 | 2026-05-10 | **kb/29-dws建模.md 新建**:1 期 DWS 单张主题宽表 `dws_usr_user_trade_1d`(用户 × 品类 × 日 交易聚合,pay 单源),承载偏好标签金额 / 次数聚合基础。设计要点:(a) DWS 单一职责日聚合,不爆窗口表(30d / yYYYY 由 TDM 跑批从 dws_1d 滚动聚合);(b) 1 期 scope 不冗余维度退化字段(仅服务标签计算),触发条件 = 上层 BI 直查 / 多维度组合 / 跨域 join 频繁,补法 = ALTER ADD COLUMN 重刷历史分区或新建第二张主题宽表(业界 1-3 张/主题);(c) 回算窗口 N=2 与 DWD 对齐(漂移连锁补偿,参 ADR-09);(d) 度量保留 13 列(pay_order_cnt + purchase_cnt + payable/pay/trade/settle/4 类 discount/point_deduct/shipping + point),砍 7 列(card_price / act_price / discount_amount_amt_cny ❓ / shipping_free / discount_point / give_cnt);(e) refund / net 度量 1 期 N/A,2 期接退款时按业务诉求选择"补 refund 列 + net 冗余"或"单独 refund 主题宽表";(f) 字段命名按业界全名 + `_amt_cny` 后缀,与 kb/27 对齐。README §2x 数仓建模索引加 kb/29 行。 | — |