题目重点:多篇 Ads onsite 只给 data modeling 方向;本文把需求侧实体、层级、状态版本、曝光与计费事件的主外键和查询取舍写成训练模型。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练情境用 advertiser→campaign→order→creative 四层结构;Netflix 实际内部模型未公开,order 也可能位于其他层级。
- 投放请求、曝光、点击和计费作为不同事件,拥有独立 id、事件时间和接收时间;不是一行广告记录的多个布尔字段。
- 预算以最小货币单位整数记录,时区、计费货币、投放地域与状态版本都需要明确;题目没有具体计费规则。
解题路线
- 先问面试目标查询:根据 order 找可投 creative、追踪订单状态与预算、统计投放/曝光/点击、还是支持 frequency cap?目标不同决定规范化表、索引和预聚合粒度。
- 规范化主实体:advertiser(id)、campaign(id,advertiser_id)、order(id,campaign_id,start/end,budget,status)、creative(id,order_id,asset_ref,approval_status)。对定向条件建独立 versioned rule set,变更生效时间与审计版本分开保存,避免回写历史曝光时解释不清。
- 不可变事件 append-only:request_id、impression_id、order_id、creative_id、user pseudonym、event_time、ingest_time、region、pricing_version。用事件 id 幂等去重;曝光账本与预算预占/结算账本分开,撤销或补偿用新事件而非覆盖旧行。
- 在线服务按状态、地域和时间索引可投 order/creative,再做频控和预算原子预占;分析侧按 order/day/region 增量聚合,迟到事件回补版本。大数据量时按时间与 advertiser/order 分区,但跨 order 的总预算需中心约束或额度分配。
手动走一遍
训练例 order O1 隶属 campaign C1,有 creative A/B。A 在 10:00 展示产生 impression I1;10:05 A 因审核停用。查询 09:00–11:00 的展示仍应能将 I1 关联到当时已批准的 A 和 O1,而不因为当前状态停用就改写历史。
规模与取舍
这不是单一 Big-O 题。在线路径的多表 join/索引访问与预算事务决定延迟;事件量 E 决定 append log 与聚合成本 O(E),维度多会增加分区与索引存储。规范化减少更新异常,预聚合换来新鲜度与回补复杂度。
易错点与追问
容易失分的边界
- 一张巨表混合 advertiser、creative、曝光和账单,状态更新会重写历史事实。
- 只保存当前定向/价格规则,无法解释过去一次投放。
- 把 request 当 impression,又把 impression 当 billable event。
- 订单预算并发扣减没有幂等键与预占语义。
- 把训练四层结构声称为 Netflix 内部真实 schema。
继续深挖
- DSP 订单状态与 Netflix 内部 order 状态如何对账?
- 广告主修改预算时,已预占和已发生曝光怎样处理?
- GDPR 删除请求如何处理 pseudonym 与审计保留冲突?
- 同一 campaign 跨地区投放如何保证总预算不超?
