03-数据契约.md 7.7 KB

数据契约

数仓与数据服务平台之间的数据接口与表结构约定。

内容
文档版本 v1.0
文档状态 待评审
更新日期 2026-06-21

修订记录

版本 日期 修订内容
v1.0 2026-06-21 初版

v2(2026-06-24):MVP 数据源改为预聚合宽表 ads_trd_group_funnel(见 §11)。 §3–§9 描述的 bitmap 方案(daily_event_bitmap / period_event_bitmap)对应"泛用漏斗",MVP 暂不落地,留作后续阶段。

1. 边界说明

本文档定义数仓与数据服务平台之间的数据契约。

职责边界:

  • 数仓负责产出 bitmap 数据。
  • PostgreSQL 是数据服务层存储。
  • FastAPI 从 PostgreSQL 读取 bitmap 并计算查询结果。
  • 数据服务平台不存储埋点明细。
  • 数据服务平台不负责数仓侧的更新、重算和明细治理。

2. 用户 ID 前提

bitmap 中的用户 ID 已经满足以下条件:

  • user_id 是自增数值。
  • user_id 适合写入 roaring bitmap。
  • 数据服务层不负责字符串用户 ID 到数值 ID 的映射。

3. bitmap 存储约定

bitmap 使用 PostgreSQL bytea 存储。

格式约定:

  • bitmap_payload 存储 roaring bitmap 的二进制序列化结果。
  • bitmap_format 标识 bitmap 格式,例如 roaring32roaring64
  • 不使用 text/base64 存储 bitmap。
  • 不使用 PostgreSQL bitmap 扩展。

4. 每日 bitmap 表

每日 bitmap 用于支持自定义时间范围查询,自定义范围最大 15 天。

建议表名:

daily_event_bitmap

字段:

字段 类型 说明
event_date date 事件日期
event_name text 事件名称
bitmap_payload bytea 该日期、该事件对应的用户 bitmap
bitmap_format text bitmap 格式,例如 roaring32
uv_count integer 该日期、该事件的 UV 冗余值
updated_at timestamp 数据更新时间

唯一键:

event_date + event_name

5. 标准周期 bitmap 表

标准周期 bitmap 用于支持快捷时间查询。

支持周期:

  • 昨日。
  • 近 7 天。
  • 近 30 天。

建议表名:

period_event_bitmap

字段:

字段 类型 说明
period_type text 周期类型:yesterdaylast_7dlast_30d
period_start date 周期开始日期
period_end date 周期结束日期
event_name text 事件名称
bitmap_payload bytea 该周期、该事件对应的用户 bitmap
bitmap_format text bitmap 格式,例如 roaring32
uv_count integer 该周期、该事件的 UV 冗余值
updated_at timestamp 数据更新时间

唯一键:

period_type + period_start + period_end + event_name

6. 日期规则

日期规则:

  • 默认最大可选日期为昨日。
  • 今天不纳入 MVP 查询范围。
  • 自定义时间范围最大 15 天。
  • 快捷时间范围由标准周期表提供。

周期定义:

  • yesterday:昨日。
  • last_7d:截至昨日的近 7 天。
  • last_30d:截至昨日的近 30 天。

7. 缺失数据规则

数据缺失时,接口必须返回明确状态,不静默补零。

缺失场景包括:

  • 某日期没有对应事件 bitmap。
  • 某标准周期没有对应事件 bitmap。
  • bitmap 格式不被服务端支持。
  • bitmap payload 无法解析。

建议状态:

ready       # 数据完整
partial     # 部分数据缺失
missing     # 查询范围数据缺失
invalid     # 数据格式错误

8. 查询使用规则

标准周期查询:

  • 如果请求时间范围命中昨日、近 7 天、近 30 天,优先读取 period_event_bitmap
  • 直接使用周期 bitmap 的 cardinality 或 uv_count 返回 UV。

自定义范围查询:

  • 读取 daily_event_bitmap 中对应日期和事件的 bitmap。
  • 每个事件在时间范围内做 bitmap OR。
  • OR 后取 cardinality 得到该事件 UV。

9. 验收标准

  • PostgreSQL 表中 bitmap 字段类型为 bytea
  • 数据服务层能区分 daily bitmap 和 period bitmap。
  • 快捷时间查询可以命中标准周期数据。
  • 自定义查询最大只需要组合 15 天 daily bitmap。
  • 缺失数据不会被静默补零。
  • 文档中不引入 Redis、PG 明细事件表或 PostgreSQL bitmap 扩展作为 MVP 依赖。

10. 后续能力域产出表(非 MVP 数据源)

MVP 仅依赖 §4 daily_event_bitmap 与 §5 period_event_bitmap。以下为其余能力域对应的数仓产出表,此处登记备查,本期不接入,字段以后续各域设计为准:

能力域 用途
ads_funnel_result_d 漏斗 固定漏斗的预计算结果
ads_retention_matrix_d 埋点完整 留存矩阵
ads_path_d 埋点完整 行为路径
dws_user_tag_wide_d 用户画像 标签宽表
dws_user_tag_long_d 用户画像 标签长表(按更新频率分层)
dim_user_segment_d 用户画像 人群包
dwd_touch_record_d 营销触达 触达记录

ads_funnel_result_d 是固定漏斗的预计算结果,与 MVP 的事件级 bitmap 组合是两种不同供给路径:MVP 泛用漏斗(步骤用户自选、非递进)用 bitmap 两表,不依赖该表。两者关系(是否后续作为固定漏斗的加速层)留待后续定。

11. MVP 数据源:拼团漏斗两张表(v3,2026-06-24)

MVP 漏斗 = 拼团漏斗,固定 5 步(漏斗顺序): 启动 start → 曝光 show → 拼团详情 detail → 下单 order → 成功 paid

数据拆成两张表,因同步逻辑不同。两表 ADS↔PG 结构一致。数据为 T+1:今天的数据次日才产出,故最大可查日始终为昨日

11.1 ads_trd_group_funnel_daily —— 单日,留全历史

每日增量 insert 新 dt,逐日累积,可回溯任意历史单日。

字段 类型 说明
dt varchar(8) 快照日 yyyyMMdd(主键)
uv_start bigint 启动 UV
uv_show bigint 曝光 UV
uv_detail bigint 拼团详情 UV
uv_order bigint 下单 UV
uv_paid bigint 成功 UV
etl_time timestamp ETL 处理时间

11.2 ads_trd_group_funnel_rolling —— 近 7/30 天,只保留最新一行

每日覆盖最新 1 行(as-of 快照),无历史——只能取当前的近 7/30 天。

字段 类型 说明
dt varchar(8) as-of 快照日 yyyyMMdd
uv_start_7d bigint 近 7 天 启动 UV
uv_show_7d bigint 近 7 天 曝光 UV
uv_detail_7d bigint 近 7 天 拼团详情 UV
uv_order_7d bigint 近 7 天 下单 UV
uv_paid_7d bigint 近 7 天 成功 UV
uv_start_30d bigint 近 30 天 启动 UV
uv_show_30d bigint 近 30 天 曝光 UV
uv_detail_30d bigint 近 30 天 拼团详情 UV
uv_order_30d bigint 近 30 天 下单 UV
uv_paid_30d bigint 近 30 天 成功 UV
etl_time timestamp ETL 处理时间

11.3 周期 → 取数路由

period 取行
day(单日) ..._daily snapshot_dtWHERE dt=:dt;否则 ORDER BY dt DESC LIMIT 1 uv_start/show/detail/order/paid
last_7d ..._rolling 唯一行 uv_*_7d
last_30d ..._rolling 唯一行 uv_*_30d
  • 单日支持历史:snapshot_dt 可选,省略=最新(昨日),给值=该天;上限昨日(T+1),今天及未来拒绝。
  • 近 7/30 天只有最新 as-of 行,不接受历史 snapshot_dt(忽略)。
  • 响应 snapshot_dt 回显实际取数那行的 dt(单日=该天;7/30 天=rolling 的 as-of 日,即"数据截至"日)。

缺失规则:目标行不存在或对应列为 NULLdata_status = missing,不补零。