维度模型数据仓库(十五) —— 多重星型模式
(五)进阶技术
10. 多重星型模式
从(五)进阶技术1. “增加列”开始,已经通过增加列和表扩展了数据仓库,在(五)进阶技术5. “快照”里增加了第二个事实表,month_end_sales_order_fact表。这之后数据仓库模式就有了两个事实表(第一个是在开始建立数据仓库时创建的sales_order_fact表)。有了这两个事实表的数据仓库就是一个正式的双星型模式。
本篇将在现有的维度数据仓库上增加一个新的星型结构。与现有的与销售关联的星型结构不同,新的星型结构关注的是产品业务领域。新的星型结构有一个事实表和一个维度表,用于存储数据仓库中的产品数据。
一个新的星型模式
图(五)- 10-1 显示了扩展后的数据仓库模式。模式中有三个星型结构。sales_order_fact表是第一个星型结构的事实表,与其相关的维度表是customer_dim、product_dim、date_dim和sales_order_attribute_dim表。month_end_sales_order_fact表是第二个星型结构的事实表。product_dim和month_dim是其对应的维度表。第一个和第二个星型结构共享product_dim维度表。第二个星型结构的事实表和月份维度数据分别来自于第一个星型结构的事实表和date_dim维度表。它们不从源数据获得数据。第三个星型模式的事实表是新建的production_fact表。它的维度除了存储在已有的date_dim和product_dim表,还有一个新的factory_dim表。第三个星型结构的数据来自源数据。
执行清单(五)- 10-1里的脚本建立第三个星型模式中的新表和对应的源数据表。
USE dw;
CREATE TABLE factory_dim (factory_sk INT NOT NULL AUTO_INCREMENT PRIMARY KEY,factory_code INT,factory_name VARCHAR(30),factory_street_address VARCHAR(50),factory_zip_code INT(5),factory_city VARCHAR(30),factory_state VARCHAR(2),version int,effective_date DATE,expiry_date DATE
);CREATE TABLE production_fact (product_sk INT
, production_date_sk INT
, factory_sk INT
, production_quantity INT
);ALTER TABLE production_fact ADD FOREIGN KEY (factory_sk)
REFERENCES factory_dim(factory_sk) ON DELETE CASCADE ON UPDATE CASCADE ;
ALTER TABLE production_fact ADD FOREIGN KEY (product_sk)
REFERENCES product_dim(product_sk) ON DELETE CASCADE ON UPDATE CASCADE ;
ALTER TABLE production_fact ADD FOREIGN KEY (production_date_sk)
REFERENCES date_dim(date_sk) ON DELETE CASCADE ON UPDATE CASCADE ;USE source;
CREATE TABLE factory_master (factory_code INT,factory_name CHAR(30),factory_street_address CHAR(50),factory_zip_code INT(5),factory_city CHAR(30),factory_state CHAR(2)
);
向新的星型结构表中导入数据
假设factory_dim表存储工厂信息,并且从称为factory_master的MySQL表获得数据。可以使用清单(五)- 10-2里的脚本初始装载工厂数据。
USE dw;
INSERT INTO factory_dim
SELECTNULL
, factory_code
, factory_name
, factory_street_address
, factory_zip_code
, factory_city
, factory_state
, 1
, CURRENT_DATE
, '2200-01-01'
FROM source.factory_master;
COMMIT;
使用Kettle转换初始装载工厂数据只需要一个表输入和一个表输出步骤即可,如图(五)- 10-2到图(五)- 10-4所示。
工厂的信息很少改变,所以可能希望在一个CSV文件里提供任何关于工厂的最新信息。在/root/data-integration/factory.csv文件中有一些示例工厂信息。 就像其它CSV源文件,需要一个过渡表装载factory.csv文件。执行清单(五)- 10-3里的脚本创建过渡表。
USE dw;
CREATE TABLE factory_stg (factory_code INT,factory_name VARCHAR(30),factory_street_address VARCHAR(50),factory_zip_code INT(5),factory_city VARCHAR(30),factory_state VARCHAR(2)
);
第三个星型结构中的production_fact事实表,从源数据库的daily_production表获取数据。执行清单(五)- 10-4里的脚本创建这个表。
USE source;
CREATE TABLE daily_production (product_code INT,production_date DATE,factory_code INT,production_quantity INT
);
可以使用清单(五)- 10-5里的脚本定期装载工厂维度表和产品事实表。注意对factory_dim表的所有列都应用SCD1。该脚本每天执行,装载前一天的产品数据。
说明:脚本里没有使用cdc_time表,是出于简化测试的目的。实际生产环境每天定期装载应该共用一个调度,也即应该把清单(五)- 10-5里的脚本并入每天定期装载脚本中,并且针对使用cdc_time表做相应的修改。
USE dw;-- 设置SCD的截止时间和生效时间
SET @pre_date = SUBDATE(CURRENT_DATE,1) ;TRUNCATE factory_stg;
LOAD DATA INFILE '/root/data-integration/factory.csv'
INTO TABLE factory_stg
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY ""
LINES TERMINATED BY '\n'
IGNORE 1 LINES
( factory_code
, factory_name
, factory_street_address
, factory_zip_code
, factory_city
, factory_state );/* SCD1 */
UPDATEfactory_dim a
, factory_stg b
SETa.factory_name = b.factory_name
, a.factory_street_address = b.factory_street_address
, a.factory_zip_code = b.factory_zip_code
, a.factory_city = b.factory_city
, a.factory_state = b.factory_state
WHERE a.factory_code = b.factory_code;/* add new factory */
INSERT INTO factory_dim
SELECTNULL
, factory_code
, factory_name
, factory_street_address
, factory_zip_code
, factory_city
, factory_state
, 1
, @pre_date
, '2200-01-01'
FROM factory_stg
WHERE factory_code NOT IN (
SELECT y.factory_code
FROM factory_dim x, factory_stg y
WHERE x.factory_code = y.factory_code );INSERT INTO production_fact
SELECTb.product_sk
, c.date_sk
, d.factory_sk
, production_quantity
FROMsource.daily_production a
, product_dim b
, date_dim c
, factory_dim d
WHEREproduction_date = @pre_date
AND a.product_code = b.product_code
AND a.production_date >= b.effective_date
AND a.production_date <= b.expiry_date
AND a.production_date = c.date
AND a.factory_code = d.factory_code ;COMMIT ;
Kettle定期装载工厂维度表和产品事实表如图(五)- 10-5到图(五)- 10-22所示。
到目前为止已经讨论了第三个星型结构里的所有表,现在做一些测试。首先需要一些工厂信息。执行清单(五)- 10-6里的脚本向源数据库的factory_master表中装载四个工厂信息。运行完清单(五)- 10-5里的脚本以后,需要把系统日期设置成任意晚于上一篇“杂项维度”设置的日期。这里设置系统日期为2015年3月18日。之后,执行清单(五)- 10-2里的脚本或对应的Kettle初始装载转换向factory_dim表装载factory_master表里的四个工厂信息。
USE source;
INSERT INTO factory_master VALUES( 1, 'First Factory', '11111 Lichtman St.', 17050,'Mechanicsburg', 'PA' )
, ( 2, 'Second Factory', '22222 Stobosky Ave.', 17055, 'Pittsburgh','PA' )
, ( 3, 'Third Factory', '33333 Fritze Rd.', 17050, 'Mechanicsburg','PA' )
, ( 4, 'Fourth Factory', '44444 Jenzen Blvd.', 17055, 'Pittsburgh','PA' );COMMIT ;
执行下面的语句查询factory_dim表,确认装载正确。查询结果显示如下。
mysql> select * from factory_dim\G
*************************** 1. row ***************************
factory_sk: 1
factory_code: 1
factory_name: First Factory
factory_street_address: 11111 Lichtman St.
factory_zip_code: 17050
factory_city: Mechanicsburg
factory_state: PA
version: 1
effective_date: 2015-03-18
expiry_date: 2200-01-01
*************************** 2. row ***************************
factory_sk: 2
factory_code: 2
factory_name: Second Factory
factory_street_address: 22222 Stobosky Ave.
factory_zip_code: 17055
factory_city: Pittsburgh
factory_state: PA
version: 1
effective_date: 2015-03-18
expiry_date: 2200-01-01
*************************** 3. row ***************************
factory_sk: 3
factory_code: 3
factory_name: Third Factory
factory_street_address: 33333 Fritze Rd.
factory_zip_code: 17050
factory_city: Mechanicsburg
factory_state: PA
version: 1
effective_date: 2015-03-18
expiry_date: 2200-01-01
*************************** 4. row ***************************
factory_sk: 4
factory_code: 4
factory_name: Fourth Factory
factory_street_address: 44444 Jenzen Blvd.
factory_zip_code: 17055
factory_city: Pittsburgh
factory_state: PA
version: 1
effective_date: 2015-03-18
expiry_date: 2200-01-01
4 rows in set (0.00 sec)
执行清单(五)- 10-7里的脚本向源数据库的daily_production表导入数据 。
USE source;
INSERT INTO daily_production VALUES(1, CURRENT_DATE, 4, 100 )
, (2, CURRENT_DATE, 3, 200 )
, (3, CURRENT_DATE, 2, 300 )
, (4, CURRENT_DATE, 1, 400 )
, (1, CURRENT_DATE, 1, 400 )
, (2, CURRENT_DATE, 2, 300 )
, (3, CURRENT_DATE, 3, 200 )
, (4, CURRENT_DATE, 4, 100 );COMMIT;
现在已经做好了测试产品定期装载的准备。先把系统日期设置为2015年3月19日,然后执行清单(五)- 10-5里的脚本或对应的Kettle定期装载作业。使用下面的SQL语句查询production_fact表,确认每天产品数据的定期装载是正确的。查询结果显示如下。
mysql> select * from production_fact;
+------------+--------------------+------------+---------------------+
| product_sk | production_date_sk | factory_sk | production_quantity |
+------------+--------------------+------------+---------------------+
| 1 | 5556 | 4 | 100 |
| 2 | 5556 | 3 | 200 |
| 4 | 5556 | 2 | 300 |
| 5 | 5556 | 1 | 400 |
| 1 | 5556 | 1 | 400 |
| 2 | 5556 | 2 | 300 |
| 4 | 5556 | 3 | 200 |
| 5 | 5556 | 4 | 100 |
+------------+--------------------+------------+---------------------+
8 rows in set (0.00 sec)
为了确认工厂维度上成功应用了SCD1,使用下面的语句查询factory_dim表。查询结果显示如下。
mysql> select * from factory_dim\G
*************************** 1. row ***************************
factory_sk: 1
factory_code: 1
factory_name: First Factory
factory_street_address: 11111 Lichtman St.
factory_zip_code: 17050
factory_city: Mechanicsburg
factory_state: PA
version: 1
effective_date: 2015-03-18
expiry_date: 2200-01-01
*************************** 2. row ***************************
factory_sk: 2
factory_code: 2
factory_name: Second Factory
factory_street_address: 24242 Bunty La.
factory_zip_code: 17055
factory_city: Pittsburgh
factory_state: PA
version: 1
effective_date: 2015-03-18
expiry_date: 2200-01-01
*************************** 3. row ***************************
factory_sk: 3
factory_code: 3
factory_name: Third Factory
factory_street_address: 37373 Burbank Dr.
factory_zip_code: 17050
factory_city: Mechanicsburg
factory_state: PA
version: 1
effective_date: 2015-03-18
expiry_date: 2200-01-01
*************************** 4. row ***************************
factory_sk: 4
factory_code: 4
factory_name: Fourth Factory
factory_street_address: 44444 Jenzen Blvd.
factory_zip_code: 17055
factory_city: Pittsburgh
factory_state: PA
version: 1
effective_date: 2015-03-18
expiry_date: 2200-01-01
4 rows in set (0.00 sec)
注意 第二和第三个工厂已经正确修改了地址。
维度模型数据仓库(十五) —— 多重星型模式相关推荐
- 「数据仓库架构」数据建模:星型模式
数据建模是现代数据工作流中的一个关键步骤,其目的是将原始数据组织成方便.高效的形式.如果一个可用的数据集易于访问,数据分析师和科学家将发现他们的工作更加容易.更快的分析和预测将导致更快的商业决策洞察力 ...
- 【DBMS 数据库管理系统】多维数据模型 ( 星型模式 | 雪片模型 | 事实群模型 | 度量 | 分布型 | 代数型 | 整体型 )
文章目录 一.星型模式 二.星型模式 缺点 三.雪片模型 四.星型模型 雪片模型 折衷方案 五.事实群模型 ( 仅做了解 ) 六.度量 一.星型模式 星型模式 是 多维数据模型 的表现形式 ; 星型模 ...
- 星型模式、雪花模式和事实星座模式
多维数据模型是最流行的数据仓库的数据模型,多维数据模型最典型的数据模式包括星型模式.雪花模式和事实星座模式,本文以实例方式展示三者的模式和区别. 1.星型模式的核心是一个大的中心表(事实表),一组小的 ...
- 45.深度解密四十五:网站盈利模式和私域流量的变现方式细致讲解
网络营销推广技术.技巧深度解密(四十五)指南: 1.本文档适合零基础以及互联网营销推广工作者,主要讲解网站的盈利模式和私域流量变现的方式问题. 2.原创版权文档,任何抄袭或者全部.部分模仿都是侵权行为 ...
- 敏捷开发“松结对编程”系列之十五:L型代码结构(编程篇之一)
本文是"松结对编程"系列的第十五篇.(松结对编程栏目目录) 之前的L型代码结构的前三篇提到过,L型代码结构的微观计划和估算过程会与一般的编程方法不同,今天正好要编写一些新代码,边写 ...
- 设计模式十五:行为型-命令模式
行为型模式:命令模式 文章目录 行为型模式:命令模式 命令模式 1.命令模式:介绍 2.命令模式:模拟场景 3.命令模式:代码实现 4.命令模式:总结 命令模式 1.命令模式:介绍 命令模式 把逻辑实 ...
- 【每天一个java设计模式(十五)】 - 命令模式
命令模式是一种数据驱动的设计模式,它属于行为型模式.请求以命令的形式包裹在对象中,并传给调用对象.调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令. 命令模式也就是一个 ...
- 第十九章行为型模式—中介者模式
文章目录 中介者模式 解决的问题 结构 实例 存在的问题 适用场景 中介者模式和代理模式的区别 代理模式 中介模式 桥接模式 总结 行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间 ...
- 设计模式(五) —— 行为型模式(中)
本篇我们将介绍四种行为型模式,分别是 解释器模式 迭代器模式 中介者模式 备忘录模式 解释器模式 我国 IT 界历来有一个汉语编程梦,虽然各方对于汉语编程争论不休,甚至上升到民族大义的高度,本文不讨论 ...
最新文章
- python 中evaluationcontext是什么_Pytorch evaluation每次运行结果不同的解决
- OD调试9—实例:深入分析代码完成软件破解
- 为vim编辑器增加行号功能
- 浅论企业文化对企业发展的影响
- elementui 表头错位解决方法
- form表单提交按钮点击事件先触发还是提交数据先触发_如何实现图片上传并保存到数据库?...
- [总]Android高级进阶之路
- jbox弹窗_关于使用 jBox 对话框的提交不能弹出问题解决方法
- rzsz的编译安装及SecureCR下Zmodem传输用法
- dagger2简单使用与理解笔记
- java毕业设计房产中介系统mybatis+源码+调试部署+系统+数据库+lw
- 15-传输层协议和应用层协议
- delphi webservice 内存释放_2020年7月——内存天梯图
- android 视频预览,预览视频 | Android 开发者 | Android Developers
- USB Audio Class (UAC)音频解读规范
- Android gatekeeper的原理介绍和代码导读
- LWIP netconn TCP UDP测试 实例
- DELPHI 颜色表
- oracle1034错误,联接oracle数据库,返回-1034,搞了两天没搞定!
- 一分钟看懂 python继承 (面试题) 万变不离其宗