数仓--DW--Hadoop数仓实践Case-15-无事实的事实表

无事实的事实表概述

  • 在多维数据仓库建模中, 有一种事实表叫做“无事实的事实表”。 普通事实表中, 通常会保存若干维度外键和多个数字型度量, 度量是事实表的关键所在。 然而在无事实的事实表中没有这些度量值, 只有多个维度外键。 表面上看, 无事实的事实表是没有意义的, 因为作为事实表, 毕竟最重要的就是度量。 但在数据仓库中, 这类事实表有其特殊用途。 无事实的事实表通常用来跟踪某种事件或者说明某些活动的范围
  • 无事实的事实表可以用来跟踪事件的发生。
    • 例如, 在给定的某一天中发生的学生参加课程的事件, 可能没有可记录的数字化事实, 但该事实行带有一个包含日期、 学生、 教师、 地点、 课程等定义良好的外键。利用无事实的事实表可以按各种维度计数上课这个事件。
    • 再比如学生注册事件, 学校需要对学生按学期进行跟踪。 维度表包括学期维度、 课程维度、 系维度、 学生维度、 注册专业维度和取得学分维度等, 而事实表由这些维度的主键组成, 事实只有注册数, 并且恒为1, 因此没有必要用单独一列来表示。 这样的事实表主要用于回答各种情况下的注册数。
  • 无事实的事实表还可以用来说明某些活动的范围, 常被用于回答“什么未发生”这样的问题。
    • 例如: 促销范围事实表。 通常销售事实表可以回答如促销商品的销售情况, 可是无法回答的一个重要问题是: 处于促销状态但尚未销售的产品包括哪些? 销售事实表所记录的仅仅是实际卖出的产品。 事实表行中不包括由于没有销售行为而销售数量为零的行, 因为如果将包含零值的产品都加到事实表中, 那么事实表将变得非常巨大。 这时, 通过建立促销范围事实表, 将商场需要促销的商品单独建立事实表保存, 然后通过这个促销范围事实表和销售事实表即可得出哪些促销商品没有销售出去。
    • 为确定当前促销的产品中哪些尚未卖出, 需要两步过程: 首先, 查询促销无事实的事实表, 确定给定时间内促销的产品。 然后从销售事实表中确定哪些产品已经卖出去了。 答案就是上述两个列表的差集。 这样的促销范围事实表只是用来说明促销活动的范围, 其中没有任何事实度量。 可能有读者会想, 建立一个单独的促销商品维度表能否达到同样的效果呢? 促销无事实的事实表包含多个维度的主键, 可以是日期、 产品、 商店、 促销等, 将这些键作为促销商品的属性是不合适的, 因为每个维度都有自己的属性集合。
  • 促销无事实的事实表看起来与销售事实表相似。 然而, 它们的粒度存在显著差别。 假设促销是以一周为持续期, 在促销范围事实表中, 将为每周每个商店中促销的产品加载一行, 无论产品是否卖出。 该事实表能够确保看到被促销定义的键之间的关系, 而与其他事件, 如产品销售无关。
  • 下面以销售订单数据仓库为例,说明如何处理源数据中没有度量的需求。 我们将建立一个无事实的事实表, 用来统计每天发布的新产品数量。 产品源数据不包含产品数量信息, 如果系统需要得到历史某一天新增产品的数量, 很显然不能简单地从数据仓库中得到。 这时就要用到无事实的事实表技术。 使用此技术可以通过持续跟踪产品发布事件来计算产品的数量。 可以创建一个只有产品(计什么数) 和日期(什么时候计数) 维度代理键的事实表。 之所以叫做无事实的事实表是因为表本身并没有数字型度量值。 这里定义的新增产品是指在某一给定日期, 源产品表中新插入的产品记录, 不包括由于SCD2新增的产品版本记录。 注意, 单从这个简单需求来看, 也可以通过查询产品维度表获取结果。 这里只为演示无事实的事实表的实现过程。

建立新产品发布的无事实的事实表

  • 在数据仓库模式中新建一个产品发布的无事实的事实表product_count_fact, 该表中只包含两个字段, 分别是引用日期维度表和产品维度表的外键, 同时这两个字段也构成了无事实事实表的逻辑主键。 下图显示了跟踪产品发布数量的数据仓库模式(只显示与无事实的事实表相关的表)。


    无事实的事实表.PNG
  • 执行下面的脚本在数据仓库模式中创建产品发布日期视图及其无事的实事实表。
use dw;
create view
    product_launch_date_dim
(   
    product_launch_date_sk,
    product_launch_date,
    month_name,
    month,
    quarter,
    year
)
as select 
    distinct date_sk,
    date,
    month_name,
    month,
    quarter,
    year
from
    product_dim a, date_dim b
where
    a.effective_date = b.date; 
-- 创建表
create table
product_count_fact (
product_sk int,
product_launch_date_sk int
);
  • 语句说明:
  • 与之前创建的很多日期角色扮演维度不同, 产品发布日期视图只获取产品生效日期, 而不是日期维度里的所有记录。 因此在定义视图的查询语句中关联了产品维度和日期维度两个表。 product_launch_date_dim维度表是日期维度表的子集。
  • 从字段定义上看, 产品维度表中的生效日期明显就是新产品的发布日期。
  • 在本示例中, 无事实的事实表的数据装载没有行级更新需求, 所以该表使用Hive默认的文本存储格式。

装载无事实的事实表

  • 下面的脚本从产品维度表向无事实的事实表装载已有的产品发布信息。 脚本里的insert语句添加所有产品的第一个版本, 即产品的首次发布日期。 这里使用Hive的窗口函数row_number正确地选取了产品发布时的生效日期, 而不是一个SCD2行的生效日期。
-- 装载无事实的事实表
insert overwrite table
    product_count_fact
select
    product_sk,date_sk
from
(
    select
        a.product_sk product_sk,
        b.date_sk date_sk,
        row_number() over (partition by a.product_code order byb.date_sk) rn
from
    product_dim a,date_dim b
where
    a.effective_date = b.date
) t
where
    rn = 1;
  • 语句说明:
  • 子查询中内连接产品维度与日期维度表, 只获取产品发布的日期。
  • 以产品编码分区, 同一个产品编码的多个版本以发布日期排序, row_number()函数为每个版本分配序号, 起别名rn。
  • 外层查询以rn=1作为过滤条件, 得到每个产品及其首次发布日期的代理键。
  • 该语句允许多次执行, 每次覆盖已有数据。
  • 其实利用产品维度表的版本字段, 更简单的写法如下:
-- 采用版本的方式进行开发
insert overwrite table
    product_count_fact
select
    a.product_sk product_sk,
    b.date_sk date_sk
from
    product_dim a,date_dim b
where
    a.effective_date = b.date anda.version = 1;

定期装载

  • 测试脚本之后,需要将脚本按照时间粒度,定时加载到Azkaban调度流中。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容