想象你是一家奶茶店的老板阿茶。清晨开门,顾客一杯接一杯地买走珍珠奶茶;中午补货,仓库里的珍珠和茶包一点点变少;下午接了个大单,从顾客下单、付款、等制作,到终于取走奶茶,中间隔着好几个环节。阿茶一个人打理生意,慢慢发现光靠一本账根本不够:每一笔卖出要记流水账;每天晚上闭店要数一遍库存;每一张订单从开始到结束要追踪进度。于是,阿茶准备了三种账本:流水账、盘点账、订单追踪账。数据仓库里的“事实表”,就是阿茶的这三本账——它是数仓中最核心的表,用来记录业务过程中产生的度量值,并把度量值组织成三种经典形态:事务事实表、周期快照事实表、累积快照事实表。

岗位关联

掌握事实表,你就掌握了数仓建模最基本的“记账能力”,能判断业务该用哪种表、怎么定粒度、怎么挂维度,设计出真正能支撑分析的数仓模型。

目录
  1. 可视化演示
  2. 事实表概览
  3. 事务事实表
  4. 周期快照事实表
  5. 累积快照事实表
  6. 粒度设计原则
  7. 维度度量关联
  8. 选型设计策略
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示数据仓库事实表的核心机制,通过总览/传输/转换/输出四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

数据仓库事实表:事实表核 事实表核心概念与度量粒度设计 事务事实表的设计原则与适用场景 核心机制可视化 数据仓库事实表整体架构与关键组件

事实表概览

阿茶每天最关心的是一件事:生意到底做了多少。不管是卖出奶茶、补货还是接受大订单,最终都能变成一句话——今天发生了一件事,产生了多少钱或者多少数量的结果。阿茶把这些话整理进账本,就成了“事实表”。在数据仓库里,事实表是记录业务过程度量值的核心表,是整个数仓模型的中心骨架。旁边那些描述“谁、何时、何地、什么”的表叫维度表,它们和事实表像齿轮一样咬合在一起。

事实表的结构并不神秘:一行就是一个业务行为的“脚印”,由两部分组成——维度外键和度量值。维度外键用来指出这行发生在哪个时间、哪个门店、哪个商品上;度量值则是真正要分析的数字,比如销售金额、销售杯数。当我们说“建立星型模型”时,说的就是用事实表做中心,把很多维度表挂在周围。

事实表的价值在于它能回答“有多少、多少钱、多频繁”这类定量问题,而且一旦设计好,可以稳定支撑数年的分析需求。设计事实表最关键的动作,就是认清业务过程、定义每行的含义、挂上正确的维度外键、放入合适的度量值。

阿茶发现,只要把“发生什么 + 数字多少”这对组合记清楚,生意账就立住了。接下来要决定的是:同一个业务过程,到底该怎么用不同的账本记录?这就要走进三种事实表类型。

事实表行=维度外键集∪度量值集\text{事实表行} = \text{维度外键集} \cup \text{度量值集}
这个公式告诉你:一张事实表的每一行,都由“指向维度的键”和“要分析的数字”拼成;缺了维度,数字没有上下文;缺了度量,外键也毫无意义。
  1. 定业务过程先明确要记录哪个业务动作,比如“顾客购买奶茶”。
    业务过程=顾客购买奶茶\text{业务过程} = \text{顾客购买奶茶}
  2. 定粒度确定每一行代表什么级别的明细,比如“单笔购买”。
    粒度=单笔购买明细\text{粒度} = \text{单笔购买明细}
  3. 关联维度把时间、门店、饮品等维度外键放入行中。
    外键集={时间键,门店键,饮品键}\text{外键集} = \{ \text{时间键}, \text{门店键}, \text{饮品键} \}
  4. 放入度量把此次业务产生的数字结果记录下来。
    度量集={杯数,金额}\text{度量集} = \{ \text{杯数}, \text{金额} \}

事务事实表

阿茶的第一本账是收银台上的流水账。每卖出一杯奶茶,她就在本子上添一行:几点几分、哪个顾客、哪款奶茶、多少钱。即使同一个顾客一口气买了五杯,她也会写五行,因为每一行代表一次独立的事件。这种“来一笔、记一笔”的记账方式,就是事务事实表。

事务事实表的每一行对应一个业务事件,是各种事实表中最细、最原始的一种。它的最大特点是“追加不更新”:新增的销售记录只会插到表尾,历史行永远不会被修改。因为它完整保留了每一次发生的细节,所以能回答“昨天卖了多少杯”“哪个时段是高峰”“哪种奶茶最畅销”这类明细分析问题。

在数仓实践中,订单流水表、支付流水表、点击日志表都是典型的事务事实表。ETL 作业通常在每日结束后,把当天新增的事务追加进事实表,并记录一个时间戳。它的粒度天然是“一次事件”,所以维度外键组合通常就是事件本身的编号,加上发生时间和地点。

阿茶盯着流水账,心里踏实了:每一分钱都有来龙去脉。但她很快发现,流水账只能告诉她“发生了什么”,却回答不了“打烊时还剩多少珍珠”。

事务行=事件发生⇒INSERT(维度外键,度量值)\text{事务行} = \text{事件发生} \Rightarrow \text{INSERT}(\text{维度外键}, \text{度量值})
这个公式说明事务事实表的核心动作是“插入”。业务事件一来,就在表末尾追加一行,过去的行保持不变。
  1. 识别业务事件一次卖奶茶的动作就是一个事件。
    事件=卖出奶茶\text{事件} = \text{卖出奶茶}
  2. 追加新行把这次事件插入到流水表末尾。
    INSERT(时间,门店,饮品,金额)\text{INSERT}(\text{时间}, \text{门店}, \text{饮品}, \text{金额})
  3. 不做更新已入账的流水永远不会被改写。
    UPDATE(已入账流水)=∅\text{UPDATE}(\text{已入账流水}) = \varnothing

周期快照事实表

晚上九点,阿茶关店后开始数库存:珍珠还剩两袋,茶包还剩一箱,杯子还剩半箱。她把数字写进另一本账——盘点账。这本账不记今天卖了多少,而是记“今天结束时还剩多少”。每天晚上拍一张“库存照片”,日子久了就是一张库存趋势图。这种固定周期、拍状态照的记账方式,就是周期快照事实表。

周期快照事实表按固定的时间周期,给每个业务维度拍一次状态快照。每一行代表“某个周期末,某个维度组合下的状态值”,比如“2024年1月1日,A门店,珍珠库存80袋”。它非常适合余额、库存量、累计值等状态型指标,因为这些数字只在某个时点才有意义,把每一笔变动都摊开反而无法直接回答“现在还剩多少”。

周期快照事实表的度量通常是“期末值”或“期间汇总值”,如账户日终余额、月累计销售额。它的半可加性特点非常明显:按门店、商品维度相加有意义,但沿时间维度相加没有意义——你不能把周一库存和周二库存加起来说成“总库存”。

阿茶的盘点账让她一眼看清库存水位,及时补货。可她还缺一本账:那些下了大订单却迟迟没来取的顾客,到底卡在哪一步?这就要用到第三本账。

快照行=(周期时点,维度键)⇒状态度量\text{快照行} = (\text{周期时点}, \text{维度键}) \Rightarrow \text{状态度量}
这个公式表示:周期快照的一行由“时点 + 维度组合”唯一确定,值是那一时刻的某种状态,而不是事件发生的过程。
  1. 固定周期每天打烊后盘点一次,形成固定节奏。
    ΔT=1日\Delta T = 1 \text{日}
  2. 组合维度键把门店、物资种类等维度打包成行身份。
    键=(门店,物资)\text{键} = (\text{门店}, \text{物资})
  3. 记录状态记下的是该时点“还剩多少”的存量。
    度量=期末库存量\text{度量} = \text{期末库存量}

累积快照事实表

某天,一位企业客户订了 100 杯定制奶茶。阿茶从下单那一刻起,就在追踪这个订单的每一步:下单、付款、开始制作、取货离开。这本追踪账最特别的地方是一个订单只占一行,随着流程推进不断更新这一行,直到订单完成才“定稿”。这种记录流程完整生命周期的记账方式,就是累积快照事实表。

累积快照事实表适用于有明确开始和结束的业务流程,如订单履约、物流派送、售后处理。它的每一行代表一个流程实例,并且会为每个关键里程碑保存一个时间戳字段。订单刚创建时,这一行只有“下单时间”;支付了,就填上“支付时间”;出库了,再填上“发货时间”。分析师可以通过各时间戳之间的差值,精确计算每个环节耗时。

相比事务事实表和周期快照表,累积快照事实表的行会被反复更新,粒度永远固定为“一个流程实例”。这让它特别擅长回答“平均配送时长”“哪一步耗时最长”“本月履约超时订单有多少”这类跨阶段分析问题。

阿茶的三本账都齐了。可是把账本铺开时,她又犯难了:同一件事,流水账能写一行,盘点账为什么也能写一行?一行到底代表什么,得先有个说法——这就是粒度。

累积行=流程实例+{里程碑时间戳}\text{累积行} = \text{流程实例} + \{ \text{里程碑时间戳} \}
这个公式说明累积快照一行就是一条完整流程,后面的时间戳集合记录了流程从起点到终点经历的关键节点时间。
  1. 流程起点下单时间是整条流程的开始。
    T0=下单时间T_0 = \text{下单时间}
  2. 记录环节支付、制作、取货等关键步骤各留一个时间戳。
    T1=支付时间,T2=完成时间,T3=取货时间T_1 = \text{支付时间}, T_2 = \text{完成时间}, T_3 = \text{取货时间}
  3. 收尾算时长顾客取货后,用终点减起点得到全流程耗时。
    履约时长=T3−T0\text{履约时长} = T_3 - T_0

粒度设计原则

阿茶发现,流水账可以一行记一笔销售,但如果顾客一次买五杯,她也可以选择把五杯合成一行,记成“5杯、50元”。两种写法都不错,但分析能力完全不同。这个“一行字到底写多细”的规则,就是事实表的粒度。粒度是事实表设计最先要回答的问题:一行到底代表什么?

事实表的粒度由维度外键组合决定。组合越细,粒度越细,行数越多;组合越粗,粒度越粗,行数越少。数仓建模有一条铁律:先声明粒度,再选维度,最后定度量。因为粒度没定,你不知道要不要包含某个维度,也不知道度量应按什么层级汇总。

举个例子,订单事实表可以按“订单行”为粒度,那么一个包含三种商品的订单会产生三行;也可以按“整单”为粒度,那这个订单只占一行,商品明细信息就要忍痛舍弃。粒度还影响存储量和性能:粒度太细,数据量巨大;粒度太粗,分析时无法下钻。因此,设计者必须先问业务方:你们最常要看哪一层细节?

阿茶终于明白了:先写清楚一行是什么,再往里面填外键和数字。账本的行格式定了,接下来还要搞清楚一件事——账本里的数字,到底能不能随便相加?

粒度=维度外键组合→一行事实\text{粒度} = \text{维度外键组合} \rightarrow \text{一行事实}
这个公式把粒度翻译成“外键组合”。组合里的维度越多、越具体,每行的事实就越细;反之就越粗。
  1. 先声明粒度设计前先用一句话定义一行代表什么。
    粒度声明=“一次购买为一行”\text{粒度声明} = \text{“一次购买为一行”}
  2. 确认外键集合决定哪些维度共同确定这一行的身份。
    外键组合=(时间,门店,饮品)\text{外键组合} = (\text{时间}, \text{门店}, \text{饮品})
  3. 由粒度推数量粒度越细,同样业务产生的行数越多。
    行数∝1粒度粗细\text{行数} \propto \frac{1}{\text{粒度粗细}}

维度度量关联

阿茶看着账本上的数字,心里冒出几个问题:销售额可以今天加明天,但库存量能周一加周二吗?单价能两个加起来说均价吗?显然都不行。事实表中的数字按“可加性”分成三类:可加、半可加、非可加。可加度量如销售金额,可以沿任意维度相加;半可加度量如库存量,沿除时间外的维度可加;非可加度量如单价、利润率,怎么加都会失真。

维度外键则相当于账本上的“标签”,每个外键都连接一张维度表。比如“门店键”指向门店维度表,告诉你这个数字来自 A 店还是 B 店;“时间键”指向日期维度表,告诉你这个数字发生在哪一天。事实表通过外键与维度表关联,才有了钻取、切片、过滤的能力。

设计事实表时,要将高频筛选和分析字段提取为外键,把真正要聚合的数字放成度量列。度量列的选取直接影响后续报表的灵活度——可加字段尽量做成数值型度量,非可加字段则保留原始值,交给应用层去计算比率,避免在事实表中直接存放易误导的派生结果。

阿茶把数字的“性格”摸清了:有的能加,有的不能加;所有数字都要靠维度标签才能说清来路。最后一步,她要根据不同问题来选账本。

{可加度量:SUM 金额 跨维度有意义半可加度量:按时间 SUM 无意义非可加度量:取 AVG 或 MAX 才有意义\begin{cases}\text{可加度量}: & \text{SUM 金额 跨维度有意义} \\\text{半可加度量}: & \text{按时间 SUM 无意义} \\\text{非可加度量}: & \text{取 AVG 或 MAX 才有意义}\end{cases}
这三条规则是度量设计的“加法宪法”:先判断一个数字能不能加、沿着哪些维度加,再决定它在事实表中的角色。
  1. 可加度量销售金额可以跨任意维度汇总,比如把多天、多店金额相加。
    ∑销售金额\sum \text{销售金额}
  2. 半可加度量库存量沿时间相加没有业务含义,只能跨门店、跨商品相加。
    ∑t=1n库存量(无业务意义)\sum_{t=1}^{n} \text{库存量} \quad (\text{无业务意义})
  3. 非可加度量单价、利润率相加会失真,更适合求平均或取最大值。
    单价‾或max⁡(单价)\overline{\text{单价}} \quad \text{或} \quad \max(\text{单价})

选型设计策略

阿茶总结出一套“对号入座”口诀:要问卖了多少钱、卖了多少杯,翻开流水账——事务事实表;要问打烊时还剩多少库存,翻开盘点账——周期快照事实表;要问一个订单从下达到取货花了多久,翻开追踪账——累积快照事实表。三种账本各回答一类问题,而且可以同时存在。

实际操作中,一个业务过程往往需要多张事实表互相配合。比如电商平台:订单明细用事务事实表,每日库存用周期快照事实表,订单履约进度用累积快照事实表。它们可以共享同一组维度表,但各自的粒度和更新策略不同。设计时,要依据业务的分析频率和查询模式来决定:高频事件用事务表保明细,周期状态用快照表提供时点视图,长链路用累积表追踪阶段耗时。

选型没有绝对的对错,但有明确的依据:先看业务要分析“事件、状态还是流程”,再定粒度,再定事实表类型。一个优秀的数仓模型,往往就是把三本账组合起来,用不同视角共同拼出业务全貌。

阿茶的三本账终于各归其位:流水账负责“发生了什么”,盘点账负责“剩下多少”,追踪账负责“走到哪一步”。真实的数仓工程师,每天都在替企业做同样的事情——用三本账把业务真相记录下来。

选型={事务表,事件明细分析周期快照表,时点状态分析累积快照表,流程进度分析\text{选型} =\begin{cases}\text{事务表}, & \text{事件明细分析} \\\text{周期快照表}, & \text{时点状态分析} \\\text{累积快照表}, & \text{流程进度分析}\end{cases}
这个分段公式是选型的决策地图:不同业务问题对应不同事实表,事件、状态、流程三种问题分别落到三种表上。
  1. 分析事件问“某段时间产生了多少笔、多少钱”,用事务表。
    场景=事件⇒事务表\text{场景} = \text{事件} \Rightarrow \text{事务表}
  2. 分析时点问“某个期末还剩多少”,用周期快照。
    场景=状态⇒快照表\text{场景} = \text{状态} \Rightarrow \text{快照表}
  3. 分析流程问“一个流程从开始到结束用了多久”,用累积快照。
    场景=流程⇒累积表\text{场景} = \text{流程} \Rightarrow \text{累积表}

AI 应用场景

电商零售:销售与库存双视角分析

阶段:数据仓库建模

解决的问题:传统零售门店靠月底人工盘点对账,既看不到每日销售明细,也看不清库存水位。通过事务事实表保存每一笔交易流水,再搭配周期快照事实表记录每日库存,就能同时回答“卖了什么”和“还剩什么”两个维度的问题。

具体案例:某连锁奶茶品牌每天凌晨运行数仓作业:事务表追加前一日全部门店销售流水,快照表生成各门店的珍珠、茶包等物料当日库存。BI 报表随之展示“销量 TOP10 饮品”和“库存预警清单”,运营团队当天就能决定哪些门店需要补货。

物流配送:订单履约环节耗时分析

阶段:业务过程建模

解决的问题:普通订单表只记录结果,看不出“从支付到接单”和“从取货到送达”分别花了多久。使用累积快照事实表,把每个订单从创建到完成的各里程碑时间戳存为一行,就能用时间戳差值计算各环节耗时。

具体案例:某同城配送平台把“下单、支付、接单、取货、送达”五个时间点全部放入累积快照事实表。分析师通过 SQL 计算全链路时长,发现“接单”环节平均耗时最长,于是优化骑手调度策略,使整体平均配送时长下降 12%。

金融账户:每日余额与风险敞口报表

阶段:周期快照建模

解决的问题:余额变动是一个个事件,但监管报表要求看“每日终态”。若只用事务事实表,需要把当天每笔入账出账累加才能得到余额,效率很低。周期快照事实表在每天收盘时记录一次账户余额,天然适配这种时点型指标。

具体案例:某支付机构每个交易日结束后,对所有账户余额执行快照任务,写入周期快照事实表。风控部门按日、按商户维度查询余额和大额异动,快速定位可疑账户,同时满足合规报送要求。

Python 演示

python68 行
# -*- coding: utf-8 -*-"""三本账最小演示事务表:事件一行;快照表:时点一行;累积表:流程一行"""from datetime import date, timedelta  def transaction_fact(events):    """事务事实表:每个事件追加一行,不更新历史"""    rows = []    for e in events:        rows.append({            "time": e["time"], "shop": e["shop"],            "drink": e["drink"], "cups": e["cups"],            "amount": e["amount"]        })    return rows  def snapshot_fact(days_stock):    """周期快照事实表:每个周期末,每个维度组合一行状态"""    rows = []    for day, stock in days_stock.items():        for item, qty in stock.items():            rows.append({"day": day, "item": item, "qty": qty})    return rows  def accum_fact(orders):    """累积快照事实表:一个订单一行,取开始与完成时间算时长"""    rows = []    for order in orders:        total_hours = (order["done"] - order["start"]).total_seconds() / 3600        rows.append({            "order_id": order["id"],            "start": order["start"],            "done": order["done"],            "hours": total_hours        })    return rows  if __name__ == "__main__":    day1 = date(2024, 1, 1)    sales = [        {"time": day1, "shop": "A店", "drink": "珍珠奶茶", "cups": 2, "amount": 30},        {"time": day1, "shop": "B店", "drink": "柠檬茶",   "cups": 1, "amount": 12}    ]    print("事务事实表(每笔销售一行):")    for r in transaction_fact(sales):        print(" ", r)     stock = {        day1: {"珍珠": 80, "茶包": 60},        day1 + timedelta(days=1): {"珍珠": 55, "茶包": 60}    }    print("周期快照事实表(每天库存一行):")    for r in snapshot_fact(stock):        print(" ", r)     orders = [        {"id": "M001",         "start": day1 + timedelta(hours=10),         "done": day1 + timedelta(hours=18)}    ]    print("累积快照事实表(一单一行):")    for r in accum_fact(orders):        print(" ", r)
目的:用 Python 模拟阿茶的三种账本——事务表追加事件行、快照表拍周期状态、累积表按流程计算时长,帮你直观对比三类事实表的行生成方式。
  1. for e in events:逐笔读取销售事件,体现事务表一次一行。
  2. rows.append({"time": e["time"], ...})每行由时间、门店等维度键和金额等度量组成。
  3. for day, stock in days_stock.items():按天遍历库存,体现周期快照的“按时点拍状态”。
  4. rows.append({"day": day, "item": item, "qty": qty})快照行 = 日期 + 物品维度 + 期末库存量。
  5. total_hours = (order["done"] - order["start"]).total_seconds() / 3600累积快照用开始、结束时间戳计算流程时长。

常见误区

误区我刚开始学数仓时,以为“事实表”里的都是数字,维度表才装文字,所以事实表里只要放金额和数量就够了。

正解事实表里除了可加的数值度量,还包含大量维度外键。这些外键虽然是整数编码,本质却指向维度描述。有时订单号、收据号等业务标识也会直接留在事实表中,称为退化维度,方便减少关联次数。

为何常见:把“事实”等同于“度量数字”,忽略了外键也是事实记录的一部分。

误区听说事务表数据最细、信息最全,我就把库存、余额全建模成事务表,结果每到期末要对账时都算不出余额。

正解事件和状态是两类不同数据。库存余额是状态,需要周期快照来呈现时点值;事务表只记录“发生了什么”,无法直接表示“发展到什么程度”。快照表按周期抓状态,才更适合余额、库存这类存量指标。

为何常见:新手偏爱“最细明细”的直觉,忽略了状态型数据更适合定时拍照的快照思路。

误区名字里都有“快照”,我以为周期快照和累积快照差不多,都是隔一段时间给数据拍照。

正解周期快照是固定周期拍状态照,比如每天记录一次库存,行与行之间互相独立;累积快照是按流程实例建行,过程中不断更新这一行直到流程结束,比如一个订单一行、持续更新里程碑。一个是按时间切片,一个是按生命周期连载。

为何常见:只看了名字中的“快照”二字,没有留意前者拍的是周期状态、后者存的是流程进度。

误区做表时习惯把能拿到的字段先全塞进一张大表,之后再慢慢清理粒度,反正数据不会丢。

正解粒度是事实表设计的先决条件。不先声明一行代表什么,就无法确定该放哪些外键、哪些度量,也无法判断表的行数与汇总方式。粒度定错,表结构、ETL、报表全部跟着错,返工成本极高。

为何常见:把事实表想象成了能“先攒数据后整理”的档案袋,而事实表更像账本——要先规定一行写多细,才能下笔记账。

误区数据库里每张表都应该有主键,所以我给事实表也加一个自增 ID 当主键,以为这样更规范。

正解事实表一般没有唯一主键,它的“身份”由维度外键组合定义,粒度决定了外键组合能否唯一标识一行。强行加自增 ID 会掩盖同一事件重复出现的问题,也让粒度校验失效,反而不利于数据质量监控。

为何常见:把 OLTP 数据库的设计习惯直接搬到数仓,忽略了事实表本质是“事件和状态的存档”,不是事务系统中的实体表。

面试题

Q1. 事实表最核心的作用是什么?

单选题 · easy

  • A.存储维度描述
  • B.记录业务度量← 正确答案
  • C.管理主数据
  • D.存储 ETL 日志

答案:B。事实表记录业务过程中的度量值,比如销售金额、销售杯数,所以选 B。维度描述归维度表管,主数据是另外的数据域,ETL 日志是运维日志,都不是事实表的职责。

Q2. 销售流水明细最适合用哪种事实表?

单选题 · easy

  • A.事务事实表← 正确答案
  • B.周期快照表
  • C.累积快照表
  • D.拉链表

答案:A。销售流水是典型的事件明细,每笔销售产生一行,只追加不更新,正对应事务事实表。周期快照适合库存、余额等状态,累积快照适合订单履约等流程,拉链表通常记录维度的历史变化。

Q3. 周期快照事实表的一行代表什么?

单选题 · easy

  • A.一次业务事件
  • B.周期时点状态← 正确答案
  • C.流程全过程
  • D.维度属性列表

答案:B。周期快照表在同一周期末给每个维度组合拍一次状态,一行就是“某个周期时点 + 某个维度组合”下的状态值。事件用事务表,流程全过程用累积快照表,维度属性是维度表的内容。

Q4. 累积快照事实表最适合回答以下哪类问题?

单选题 · mid

  • A.昨日销售金额多少
  • B.每日期末库存多少
  • C.订单履约耗时多久← 正确答案
  • D.本月渠道占比多少

答案:C。累积快照表把每个流程实例存成一行,记录各里程碑时间戳,计算时间差就能回答“订单从下单到签收花了多久”。销售额用事务表,期末库存用周期快照表,渠道占比依赖维度聚合。

Q5. 银行账户余额历史分析应优先选择?

单选题 · mid

  • A.事务事实表
  • B.周期快照表← 正确答案
  • C.累积快照表
  • D.维度表

答案:B。余额是时点状态,每天记录一次日终余额形成快照,能直接支持日均余额、余额趋势等分析。事务表只记录每笔变动,很难直接给出时点状态;累积快照面向流程,维度表不存度量。

Q6. 事实表的“粒度”指的是什么?

单选题 · mid

  • A.表的数据总行数
  • B.一行的业务细节← 正确答案
  • C.磁盘占用多少
  • D.字段长度大小

答案:B。粒度定义一行事实代表什么级别的业务细节,比如“一次购买为一行”还是“一个订单行为一行”。行数、磁盘占用、字段长度都是粒度确定后的结果,不是粒度本身。

Q7. 关于事实表设计原则,正确的有?

多选题 · hard

  • A.粒度先于维度设计← 正确答案
  • B.外键连接维度表← 正确答案
  • C.先定粒度再定度量← 正确答案
  • D.事实表可以没有外键

答案:ABC。事实表设计顺序是先声明粒度,再选维度外键,最后定度量,所以 A、C 正确。维度外键是事实表与维度表关联的桥梁,B 也正确。D 错误,没有外键的事实表既无法关联维度,也无法定义粒度。

Q8. 关于三种事实表的特性,正确的是?

多选题 · mid

  • A.事务表只增不改← 正确答案
  • B.快照表记录时点← 正确答案
  • C.累积表一行一流← 正确答案
  • D.三种表互斥选一

答案:ABC。事务表追加不更新,周期快照表拍时点状态,累积快照表一个流程一行,A、B、C 都正确。D 错误,三种表可以组合使用,同一业务可同时保留事务表和累积表来支持不同分析视角。

Q9. 关于事实表可加性的说法,正确的是?

多选题 · hard

  • A.销售额可跨维相加← 正确答案
  • B.库存按时间相加无意义← 正确答案
  • C.单价可以直接相加
  • D.比率不能简单求和← 正确答案

答案:ABD。销售额是可加度量,可跨维度求和;库存是半可加度量,沿时间相加没有业务含义;比率是非可加度量,直接求和会得出错误结果,所以 A、B、D 正确。单价相加会失真,C 错误。

Q10. 关于三种事实表组合使用的说法正确的是?

单选题 · extreme

  • A.同一业务可同时建多种事实表← 正确答案
  • B.同一业务只能建一种事实表
  • C.快照表与累积表完全对立
  • D.事务表必须包含代理键主键

答案:A。同一业务过程可以同时建立事务事实表、周期快照表和累积快照表,分别服务事件、状态、流程三类分析,所以选 A。B 过于绝对,C 错误——两者解决的问题不同但互补,D 错误——事实表通常没有唯一主键,由外键组合定义粒度。