桥接表解决什么问题
当事实与维度之间存在多对多关系(一笔订单用多张促销券、一篇文章挂多个标签),直接关联会让事实行数成倍虚增。桥接表把关系单独存成一张表,并带上权重,使金额与数量可以按约定分摊到每个关联成员。
基本信息
| 结构 | 主实体键 + 关联键 + 权重(合计一般归一到 1) |
|---|---|
| 作用 | 表达多对多关系并支持分摊计算 |
| 使用方式 | 事实表关联桥接表,再关联关联维度表 |
| 权重约定 | 同一主实体下所有关联的权重合计为 1 |
| 替代方案 | 反向事实表,用于以关联成员为主视角统计 |
典型使用场景
- 一笔订单使用多张促销券,券的核销金额需要分摊到每张券
- 一篇文章挂多个标签或分类,标签维度的汇总需要可分摊也可去重
- 成本分摊:一次采购服务多个部门,按比例摊到部门维度
- 渠道归因:一笔成交由多个触点促成,按模型权重分配贡献
- 商品多类目归属:同一商品挂在多个类目下,需要按权重或去重统计
桥接表与分摊查询
桥接表与分摊查询
-- 桥接表:一笔订单对多张促销券,权重合计为 1
-- bridge_order_promo(order_key, promo_key, weight)
-- 分摊统计:金额乘以权重后按券汇总,总额与订单侧一致
SELECT p.promo_name, sum(f.pay_amt * b.weight) AS share_amt
FROM fact_order f
JOIN bridge_order_promo b ON f.order_key = b.order_key -- 先展开关系
JOIN dim_promo p ON b.promo_key = p.promo_key
GROUP BY p.promo_name;
-- 非分摊口径:只统计覆盖了促销的订单数,注意去重
SELECT count(DISTINCT f.order_key) FROM fact_order f
JOIN bridge_order_promo b ON f.order_key = b.order_key;多对多的三种处理
| 处理方式 | 能否分摊 | 适用判断 |
|---|---|---|
| 分隔串存事实表 | 否 | 无法 join,只能模糊匹配,除极小场景外不建议 |
| 桥接表 | 是(带权重) | 需要按成员分摊金额或数量时使用 |
| 反向事实表 | 否 | 以关联成员为主视角统计覆盖数量时使用 |
分摊口径与非分摊口径必须显式区分并写进文档:前者把总额拆给多个成员,后者统计的是覆盖关系数量。两者混用会出现「各成员之和大于总额」的现象,使用者会直接怀疑数据错误。
权重合计不为 1 时,分摊结果的总和与事实侧总额对不上。加载桥接表后必须做一次权重合计校验,发现不等于 1 的新增关系要拦在入仓前。