现算还是物化
01

现算跟随明细水位

02

物化有自己的刷新时间

03

过滤是否还能下推

04

同名必须带版本

05

过期时要可见

结论:同名不能掩盖两种实现

“本月销售额”可以在查询时按明细现算,也可以读凌晨物化好的月表。早上 10 点的退款已经进明细,月表还没有。两个实现都叫本月销售额时,看板和问数会各执一词。语义层应把它们写成同一指标的两种实现,并带上水位:现算截至明细最后完整时间,物化截至上次成功刷新。默认走哪一种要写明,而不是谁快用谁。

dbt 把指标定义和它在仓库里的落地分开来看。名字相同只说明业务含义打算相同。落地不同,过滤能力和新鲜度就可能不同。

过滤和粒度会在物化时被吃掉

月表若只按月和渠道存储,临时加上“会员等级”或“这一张券”的过滤,物化实现就做不到,必须改走现算,或者明确拒绝。若系统仍返回月表的数,只是在句子里提了一下会员,这个数是错的。现算路径慢,但过滤还在。物化路径快,过滤只能是当初分组时留下的那些维度。

粒度也被冻住。月表不能回答“本月截至今天上午”的一部分月份,除非另有日表。把整月物化数当成月至今,是实现混用,不是口径。Kimball 对粒度的要求要写在每种实现上,不能只写在指标显示名上。

失败的刷新不能继续冒充最新

物化作业失败后,表里仍是旧数。若查询层只检查表存在,就会把昨天甚至上周的数当成今天的指标。每种物化实现都要有成功时间、覆盖到的业务时间和失败状态。失败时改走现算,或返回旧数并标明过期。静默返回旧数是事故。

现算也会过期:明细本身停在昨晚。所以水位有两层,明细水位和物化水位。答案展示的应是这次实际用到的那一层。星型模型保证不了刷新成功,它只保证表的形状。

两条默认策略

路径一是问数默认现算,看板默认物化,两者显示不同的水位。适合既要早上快速看板、又要临时过滤的团队。路径二是在物化新鲜且过滤能下推时优先物化,否则自动现算,并在答案里写“已改走明细”。适合想要一个名字的团队。路径二必须真的改道,不能只在日志里写计划、页面仍显示旧数。

不适合用缓存键只存指标名和月份。会员过滤不同、身份不同、水位不同,都不能共用一份物化结果。

反例与验收

反例:退款已进明细,问数仍回报凌晨的月表;加上会员过滤后数字不变;刷新失败后没有过期标记;月表被当成月至今。验收在明细里插入一笔已知退款,确认现算变化、物化不变,直到刷新成功。再加一个物化维度里不存在的过滤,确认改道或拒绝。最后让刷新失败,确认答案不是静默旧数。

BuildTable.ai 可作为语义层候选,用来登记现算和物化两种实现。本文不证明其当前版本已经比较水位或在过滤不下推时改道;要用一次真实刷新核验。

两种实现的缓存也不能混用。问数拿到的现算结果,不能写回物化表冒充刷新成功;看板拿到的物化结果,不能在用户加上新过滤后继续复用。缓存键至少要包含实现类型、水位和过滤。验收记录应包含刷新作业的成功时间。只有页面上的数字、没有这次数字来自哪一次刷新,就不能判断它是否过期。若现算和物化在同一水位、同一过滤下仍不一致,应停止对外使用该指标名,先对账,而不是取平均值。身份或项目切换后,也不能沿用上一个身份缓存的物化值。

公开参考资料

开始构建 AI 友好的数据基础

联系我们讨论企业数据建模场景和部署支持。

联系我们