<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Hideto &#187; Data Warehouse</title>
	<atom:link href="http://rubylog.com/tag/data-warehouse/feed/" rel="self" type="application/rss+xml" />
	<link>http://rubylog.com</link>
	<description>非典型性专题研究</description>
	<lastBuildDate>Thu, 26 Nov 2009 08:28:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>数据仓库实践 &#8212; 《Dimensional Data Warehousing with MySQL》</title>
		<link>http://rubylog.com/dimensional-data-warehousing-with-mysql/</link>
		<comments>http://rubylog.com/dimensional-data-warehousing-with-mysql/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 08:27:02 +0000</pubDate>
		<dc:creator>Hideto</dc:creator>
				<category><![CDATA[Data Warehouse]]></category>

		<guid isPermaLink="false">http://rubylog.com/?p=86</guid>
		<description><![CDATA[数据仓库基础
基本组件
star schema：维度数据仓库的数据库结构
surrogate key：数据仓库表里作为主键的列
除了star schema，也有在数据仓库中用snowflake schema的，不过后者更难建模、不容易理解和实现、性能较前者差
维度数据仓库包括两种类型的关系数据库表：fact表和dimension表
一个fact表+周围多个dimension表就是一个star结构，multi-start结构则有多个fact表，其中多个fact表共享一些共用的dimension表
fact表一般后缀为fact，而dimension表后缀为dim
fact表包含多个可度量的事实，可度量的事实成为measure，dimension表对measure进行分类
每个dimension表包含一个surrogate key列，列名后缀为sk，dimension里每个sk列在fact表都有一个类似的列

dimension表里的sk列是主键，一般sk的值为顺序的数字且不含业务含义
Dimension历史
dimension会随着时间而改变，比如用户会更改地址、产品改名或重新分类、销售订单修正等等
我们必须维护dimension的历史，这样才能保证就的销售订单指向旧的产品分类，而新的销售订单指向新的产品分类
Slowly Changing Dimension(SCD)是维度数据仓库里实现dimension历史的技术
SCD包含三种类型：

SCD1：总是用新的数据覆盖老的数据，不保存历史
SCD2：总是创建新版本的dimension，不修改和删除老的数据
SCD3：保存有限的dimension历史，如对customer_address列维护一个previous_customer_address列

Measure Additivity
Measure的一个重要特质是Measure Additivity
如果一个measure在所有情况下都可以sum，那么称这个measure是fully-addative
如果一个measure只能在某些情况下做sum，那么称这个measure是semi-addative
也就是说，如果一个measure在任意一个dimension上计算的总和与任意其他一个dimension上计算的总、其他dimension任意组合上计算的总和都相等，那么这个measure就是fully additive的
维度查询
维度查询包括三个常见类型：

aggregation：对fact进行求和
specific：对特定的dimension值进行fact查询和求和
inside out：基于fact的measure值条件进行查询

ETL
源数据提取
有两种源数据提取方式：

Whole Source：提取整个源数据，这种模式对参考性质的数据源比较合适，如邮政编码
Change Data Capture(CDC)：只提取增量改动的数据，如果数据源特别大而且提取整个数据效率低时适用，通常作为动态数据源的提取方式

提取数据时可以采用Pull后Push两种方式
组装Date Dimension
在数据仓库里时间维度是最重要的，因为数据仓库的首要功能就是存储历史数据，所以数据仓库里始终有时间维度
三种常见的组装date dimension的技术：

提前组装：比如提前准备好十年内所有的date dimension
每天一个date：每天准备一条新的date记录
从源数据加载date：从源数据加载仅仅被使用的date

初始化组装
在开始数据仓库操作之前的第一步就是加载历史数据
最好有一个Source Data到Data Warehouse的映射文档来列出需要哪些数据源、数据格式已经对应的fact/dimension表，然后写初始化脚本来加载数据
定期组装
和初始化组装一样，最好有一个文档来列出源数据、数据仓库表、提取模式(Whole/CDC、Push/Pull)、加载类型(SCD、Pre-populate)等等，然后写加载数据的脚本
定期组装调度
Windows控制面板里添加任务向导或者Linux下crontab程序都可以添加定时调度任务
演进
添加列
数据仓库常见的需求是添加列到已有的dimension和fact表

更改dimension和fact表之后需要修改定期组装脚本
按需组装
有时候在定期组装之外需要一些按需组装，比如促销销售的源数据只有在促销阶段才有
这时通常需要dimension、fact表的更改和一些按需组装的脚本
Dimension子集
由于有些用户不会使用所有的dimension数据，比如用户只关心month，不关心date，所以我们可以提供一个month_dim(date_dim的子集)
Dimension角色扮演
有时候一个fact需要使用同一个dimension多次，比如销售订单fact需要两个date，一个是下订单时间一个是发送订单时间，这时可以用dimension角色扮演技术来实现。
有两种dimension角色扮演的类型：表别名和数据库视图
表别名就是指在查询时对同一个表取多个不同的别名来区分，以满足查询多次同一个dimension的目的
数据库视图就是对已有的dimension根据使用次数建多个视图来满足多次使用同一dimension的目的
快照
有些用户可能只需要特定时间的数据，换句话说，他们只需要数据的快照
有两种类型的数据快照：周期性快照和累积性快照
周期性快照是fact在一定周期内的sum总和，如monthly fact表在每个月结束时会有一个快照
累积性快照跟踪fact的更改，如销售订单的持续累积数据
Dimension Hierarchy
大部分dimension有一个或多个层次结构，如date dimension有一个分4级的层次结构：year级别、quarter级别、month级别和date级别，而且只有year-quarter-month-date这一条单一路径
同一主题下的列可以归为一组，而且组的成员至少包含另一个成员，如果month包含date，这时就会形成一个层次结构，比如year-quarter-month-date是date dimension的一个Hierarchy
在Hierarchy上可以做grouping和drilling
grouping查询会对fact按dimension做group by，但是只显示到最低级别的数据，而drilling则是显示dimension各种级别的数据
多路径Hierarchy和不平整Hierarchy
有时候一个Hierarchy会有多条路径，比如year-quarter-month或year-campaign-month，所以查询时可以按不同的路径进行drilling
Hierarchy中如果不包含一个或多个级别的数据，那么称之为不平整(Ragged) Hierarchy，例如某几个month没有campaign session，那么month dimension被称为ragged campaign hierarchy
如果某几个month不存在campaign，则用month代替，最终drilling查询结果会将不存在campaign的行用month代替(导致多行相同的month)，而有campaign的行的metric值是对应month的metric值的总和
Dimension退化
当用户不需要某部分dimension数据时，可以将dimension退化，移除哪些不用的数据，从而增加查询性能
比如退化order_dim表的步骤：

将order_number列加到sales_order_fact表
将已有的order_number从order_dim移到sales_order_fact表
从sales_order_fact表中移除order_sk列
移除order_dim表

Junk Dimension
有些dimension字段的值的种类特别少，比如只有yes和no两种值的一些字段，它们应该放在称为junk dimension的dimension表里

Multi-Star Schema
如果数据仓库里有多个fact表，则应称之为Multi-Star Schema
高级技术
非直接的数据源
如果数据源由于粒度不同不能直接加载到数据仓库，则需要ETL时做一些转换
无事实的fact表
有时候需要度量一些源数据里没有的数据，比如产品计数，我们可以建立一个无事实的fact表来实现

延迟fact
有时候fact表的数据有延迟，导致快照fact表的数据不对，这时需要改进定期fact组装脚本来处理这种延迟数据
合并Dimension
随着数据仓库有些dimension表有重复的数据，我们可以将它们合并到一个单独的dimension
累积度量
有时候需要跟踪一些累积的度量，比如month-end balance，这时就需要增加额外的measure，并且在加载数据时注意加上之前的值
范围Dimension
一些连续的值的范围构成范围(band) dimension，比如销售订单的数量0.01-15000为&#8221;LOW&#8221;，15000.01-30000.00为&#8221;MED&#8221;，30000.01-99999999.99为&#8221;HIGH&#8221;
这时可以为这个dimension单独见一个band dimension表，然后fact表添加sk即可

]]></description>
			<content:encoded><![CDATA[<p><span style="color: #0000ff;"><strong>数据仓库基础</strong></span></p>
<p><strong>基本组件</strong><br />
star schema：维度数据仓库的数据库结构<br />
surrogate key：数据仓库表里作为主键的列<br />
除了star schema，也有在数据仓库中用snowflake schema的，不过后者更难建模、不容易理解和实现、性能较前者差<br />
维度数据仓库包括两种类型的关系数据库表：fact表和dimension表<br />
一个fact表+周围多个dimension表就是一个star结构，multi-start结构则有多个fact表，其中多个fact表共享一些共用的dimension表<br />
fact表一般后缀为fact，而dimension表后缀为dim<br />
fact表包含多个可度量的事实，可度量的事实成为measure，dimension表对measure进行分类<br />
每个dimension表包含一个surrogate key列，列名后缀为sk，dimension里每个sk列在fact表都有一个类似的列<br />
<a href="http://rubylog.com/wp-content/uploads/2009/11/110.PNG"><img class="alignnone size-full wp-image-87" title="1" src="http://rubylog.com/wp-content/uploads/2009/11/110.PNG" alt="1" width="701" height="498" /></a><br />
dimension表里的sk列是主键，一般sk的值为顺序的数字且不含业务含义</p>
<p><strong>Dimension历史</strong><br />
dimension会随着时间而改变，比如用户会更改地址、产品改名或重新分类、销售订单修正等等<br />
我们必须维护dimension的历史，这样才能保证就的销售订单指向旧的产品分类，而新的销售订单指向新的产品分类<br />
Slowly Changing Dimension(SCD)是维度数据仓库里实现dimension历史的技术<br />
SCD包含三种类型：</p>
<ol>
<li>SCD1：总是用新的数据覆盖老的数据，不保存历史</li>
<li>SCD2：总是创建新版本的dimension，不修改和删除老的数据</li>
<li>SCD3：保存有限的dimension历史，如对customer_address列维护一个previous_customer_address列</li>
</ol>
<p><strong>Measure Additivity</strong><br />
Measure的一个重要特质是Measure Additivity<br />
如果一个measure在所有情况下都可以sum，那么称这个measure是fully-addative<br />
如果一个measure只能在某些情况下做sum，那么称这个measure是semi-addative<br />
也就是说，如果一个measure在任意一个dimension上计算的总和与任意其他一个dimension上计算的总、其他dimension任意组合上计算的总和都相等，那么这个measure就是fully additive的</p>
<p><strong>维度查询</strong><br />
维度查询包括三个常见类型：</p>
<ol>
<li>aggregation：对fact进行求和</li>
<li>specific：对特定的dimension值进行fact查询和求和</li>
<li>inside out：基于fact的measure值条件进行查询</li>
</ol>
<p><span style="color: #0000ff;"><strong>ETL</strong></span></p>
<p><strong>源数据提取</strong><br />
有两种源数据提取方式：</p>
<ol>
<li>Whole Source：提取整个源数据，这种模式对参考性质的数据源比较合适，如邮政编码</li>
<li>Change Data Capture(CDC)：只提取增量改动的数据，如果数据源特别大而且提取整个数据效率低时适用，通常作为动态数据源的提取方式</li>
</ol>
<p>提取数据时可以采用Pull后Push两种方式</p>
<p><strong>组装Date Dimension</strong><br />
在数据仓库里时间维度是最重要的，因为数据仓库的首要功能就是存储历史数据，所以数据仓库里始终有时间维度<br />
三种常见的组装date dimension的技术：</p>
<ol>
<li>提前组装：比如提前准备好十年内所有的date dimension</li>
<li>每天一个date：每天准备一条新的date记录</li>
<li>从源数据加载date：从源数据加载仅仅被使用的date</li>
</ol>
<p><strong>初始化组装</strong><br />
在开始数据仓库操作之前的第一步就是加载历史数据<br />
最好有一个Source Data到Data Warehouse的映射文档来列出需要哪些数据源、数据格式已经对应的fact/dimension表，然后写初始化脚本来加载数据</p>
<p><strong>定期组装</strong><br />
和初始化组装一样，最好有一个文档来列出源数据、数据仓库表、提取模式(Whole/CDC、Push/Pull)、加载类型(SCD、Pre-populate)等等，然后写加载数据的脚本</p>
<p><strong>定期组装调度</strong><br />
Windows控制面板里添加任务向导或者Linux下crontab程序都可以添加定时调度任务</p>
<p><span style="color: #0000ff;"><strong>演进</strong></span></p>
<p><strong>添加列</strong><br />
数据仓库常见的需求是添加列到已有的dimension和fact表<br />
<a href="http://rubylog.com/wp-content/uploads/2009/11/22.PNG"><img class="alignnone size-full wp-image-89" title="2" src="http://rubylog.com/wp-content/uploads/2009/11/22.PNG" alt="2" width="701" height="498" /></a><br />
更改dimension和fact表之后需要修改定期组装脚本</p>
<p><strong>按需组装</strong><br />
有时候在定期组装之外需要一些按需组装，比如促销销售的源数据只有在促销阶段才有<br />
这时通常需要dimension、fact表的更改和一些按需组装的脚本</p>
<p><strong>Dimension子集</strong><br />
由于有些用户不会使用所有的dimension数据，比如用户只关心month，不关心date，所以我们可以提供一个month_dim(date_dim的子集)</p>
<p><strong>Dimension角色扮演</strong><br />
有时候一个fact需要使用同一个dimension多次，比如销售订单fact需要两个date，一个是下订单时间一个是发送订单时间，这时可以用dimension角色扮演技术来实现。<br />
有两种dimension角色扮演的类型：表别名和数据库视图<br />
表别名就是指在查询时对同一个表取多个不同的别名来区分，以满足查询多次同一个dimension的目的<br />
数据库视图就是对已有的dimension根据使用次数建多个视图来满足多次使用同一dimension的目的</p>
<p><strong>快照</strong><br />
有些用户可能只需要特定时间的数据，换句话说，他们只需要数据的快照<br />
有两种类型的数据快照：周期性快照和累积性快照<br />
周期性快照是fact在一定周期内的sum总和，如monthly fact表在每个月结束时会有一个快照<br />
累积性快照跟踪fact的更改，如销售订单的持续累积数据</p>
<p><strong>Dimension Hierarchy</strong><br />
大部分dimension有一个或多个层次结构，如date dimension有一个分4级的层次结构：year级别、quarter级别、month级别和date级别，而且只有year-quarter-month-date这一条单一路径<br />
同一主题下的列可以归为一组，而且组的成员至少包含另一个成员，如果month包含date，这时就会形成一个层次结构，比如year-quarter-month-date是date dimension的一个Hierarchy<br />
在Hierarchy上可以做grouping和drilling<br />
grouping查询会对fact按dimension做group by，但是只显示到最低级别的数据，而drilling则是显示dimension各种级别的数据</p>
<p><strong>多路径Hierarchy和不平整Hierarchy</strong><br />
有时候一个Hierarchy会有多条路径，比如year-quarter-month或year-campaign-month，所以查询时可以按不同的路径进行drilling<br />
Hierarchy中如果不包含一个或多个级别的数据，那么称之为不平整(Ragged) Hierarchy，例如某几个month没有campaign session，那么month dimension被称为ragged campaign hierarchy<br />
如果某几个month不存在campaign，则用month代替，最终drilling查询结果会将不存在campaign的行用month代替(导致多行相同的month)，而有campaign的行的metric值是对应month的metric值的总和</p>
<p><strong>Dimension退化</strong><br />
当用户不需要某部分dimension数据时，可以将dimension退化，移除哪些不用的数据，从而增加查询性能<br />
比如退化order_dim表的步骤：</p>
<ol>
<li>将order_number列加到sales_order_fact表</li>
<li>将已有的order_number从order_dim移到sales_order_fact表</li>
<li>从sales_order_fact表中移除order_sk列</li>
<li>移除order_dim表</li>
</ol>
<p><strong>Junk Dimension</strong><br />
有些dimension字段的值的种类特别少，比如只有yes和no两种值的一些字段，它们应该放在称为junk dimension的dimension表里<br />
<a href="http://rubylog.com/wp-content/uploads/2009/11/32.PNG"><img class="alignnone size-full wp-image-90" title="3" src="http://rubylog.com/wp-content/uploads/2009/11/32.PNG" alt="3" width="700" height="550" /></a></p>
<p><strong>Multi-Star Schema</strong><br />
如果数据仓库里有多个fact表，则应称之为Multi-Star Schema</p>
<p><span style="color: #0000ff;"><strong>高级技术</strong></span></p>
<p><strong>非直接的数据源</strong><br />
如果数据源由于粒度不同不能直接加载到数据仓库，则需要ETL时做一些转换</p>
<p><strong>无事实的fact表</strong><br />
有时候需要度量一些源数据里没有的数据，比如产品计数，我们可以建立一个无事实的fact表来实现<br />
<a href="http://rubylog.com/wp-content/uploads/2009/11/42.PNG"><img class="alignnone size-full wp-image-91" title="4" src="http://rubylog.com/wp-content/uploads/2009/11/42.PNG" alt="4" width="699" height="217" /></a></p>
<p><strong>延迟fact</strong><br />
有时候fact表的数据有延迟，导致快照fact表的数据不对，这时需要改进定期fact组装脚本来处理这种延迟数据</p>
<p><strong>合并Dimension</strong><br />
随着数据仓库有些dimension表有重复的数据，我们可以将它们合并到一个单独的dimension</p>
<p><strong>累积度量</strong><br />
有时候需要跟踪一些累积的度量，比如month-end balance，这时就需要增加额外的measure，并且在加载数据时注意加上之前的值</p>
<p><strong>范围Dimension</strong><br />
一些连续的值的范围构成范围(band) dimension，比如销售订单的数量0.01-15000为&#8221;LOW&#8221;，15000.01-30000.00为&#8221;MED&#8221;，30000.01-99999999.99为&#8221;HIGH&#8221;<br />
这时可以为这个dimension单独见一个band dimension表，然后fact表添加sk即可<br />
<a href="http://rubylog.com/wp-content/uploads/2009/11/52.PNG"><img class="alignnone size-full wp-image-88" title="5" src="http://rubylog.com/wp-content/uploads/2009/11/52.PNG" alt="5" width="700" height="522" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://rubylog.com/dimensional-data-warehousing-with-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
