轉自:http://www.cnblogs.com/en-heng/p/5239311.html
1. 數據倉庫的相關概念
OLAP
大部分數據庫系統的主要任務是執行聯機事務處理和查詢處理,這種處理被稱為OLTP(Online Transaction Processing, OLTP),面向的是顧客,諸如:辦事員、DBA等。而數據倉庫主要面向知識工人(如經理、主管等)提供數據分析處理,這種處理被稱為OLAP(Online Analysis Processing)。OLTP管理的是當前數據,比較瑣碎,很難用於做決策。而OLAP管理的是大量歷史數據,提供匯總與聚集機制,並在不同的維度、不同的粒度存儲和管理信息。
特征 | OLTP | OLAP |
---|---|---|
面向 | 辦事員、DBA | 知識工人 |
DB設計 | 基於ER,面向應用 | 星形/雪花,面向主題 |
數據 | 當前的、確保更新 | 歷史的、跨時間維護 |
視圖 | 詳細、一般關系 | 匯總的、多維的 |
訪問 | 讀/寫 | 大多數為讀 |
度量 | 事務吞吐量 | 查詢吞吐量、訪問時間 |
舉個簡單的例子:我們會用OLTP去管理app名稱與app類別的映射關系;而分析某一周app(和app類別)的UV,則會使用OLAP;並且OLAP提供了數據的多維觀察——比如:在某周在華為手機上top100用戶的APP。
Fact Table
事實表(Fact Table)是中心表,包含了大批數據並不冗余,其數據列可分為兩類:
- 包含大量數據事實的列;
- 與維表(Dimension Table)的primary key相對應的foreign key。
Lookup Table
Lookup Table包含對事實表的某些列進行擴充說明的字段。在Kylin的quick start中給出sample cube(kylin_sales_cube)——其Fact Table為購買記錄,lookup table有兩個:用於對購買日期PART_DT、商品的LEAF_CATEG_ID與LSTG_SITE_ID字段進行擴展說明。
Dimension
維表(Dimension Table)是由fact table與lookup table邏輯抽象出來的表,包含了多個相關的列(即dimension),以提供對數據的多維觀察;其中dimension的值的數目稱為cardinatily。在kylin_sales_cube的事實表的LSTG_FORMAT_NAME
被單獨抽出來做一個dimension,可與其他維度組合分析數據。
Star Schema
星形模式(Star Schema)包含一個或多個事實表、一組維表,其中維表的primary key與事實表的foreign key相對應。這種模式很像星光四射,維表顯示在圍繞事實表的射線上。下圖是我根據某數據源所建立的星形模式:
Cube
cube是所有的dimensions組合,任一dimensions的組合稱為cuboid。因此,包含nn個dimensions的cube有2n2n個cuboid,如下圖所示:
2. Kylin介紹
Dimension
為了減少cuboid的數目,Kylin將Dimension分為四種類型:
- Normal,為最常見的類型,與所有其他的dimension組合構成cuboid。
-
Mandatory,在每一次查詢中都會用到dimension,在下圖中A為Mandatory dimension,則與B、C總共構成了4個cuboid,相較於normal dimension的cuboid(23=823=8)減少了一半。
-
Hierarchy,為帶層級的dimension,比如說:省份->城市, 年->季度->月->周->日;以用於做drill down。
- Derived,指該dimensions與維表的primary key是一一對應關系,可以更有效地減少cuboid數量,詳細的解釋參看這里;並且derived dimension只能由lookup table的列生成。
然而,Kylin的Hierarchy dimensions並沒有做集合包含約束,比如:kylin_sales_cube定義Hierarchy dimension為META_CATEG_NAME->CATEG_LVL2_NAME->CATEG_LVL3_NAME
,但是同一個CATEG_LVL2_NAME
可以對應不同META_CATEG_NAME
。因此,hierarchy 顯得非常雞肋,以至於在Kylin后台處理時被廢棄了(詳見Li Yang在mail group中所說):
@Julian, plan to refactor the underlying aggregation group in Q4. Will drop
hierarchy concept in the backend, however in the frontend for ease of
understanding, may still call it hierarchy.
Measure
Measure為事實表的列度量,Kylin提供諸如:
- Sum
- Count
- Max
- Min
- Average
- Distinct Count (based on HyperLogLog)
等函數,一般配合group by dimesion
使用。
3. 實戰
下面的SQL語句是在kylin_sales_cube build成功后執行的。
sql命令select * from kylin_sales
,得到fact table所緩存的列——均為dimension的主key、measure中所需計算的字段。
各個時間段內的銷售額及購買量:
select part_dt, sum(price) as total_selled, count(distinct seller_id) as sellers from kylin_sales group by part_dt order by part_dt
查詢某一時間的銷售額及購買量,
select part_dt, sum(price) as total_selled, count(distinct seller_id) as sellers from kylin_sales where part_dt = '2014-01-01' group by part_dt
發現報錯:
Error while compiling generated Java code: public static class Record3_0 implements java.io.Serializable { public java.math.BigDecimal f0; public boolean f1; public org.apache.kylin.common.hll.HyperLogLogPlusCounter f2; public Record3_0(java.math.BigDecimal f0, boolean f1, ...
這是因為part_dt是date類型,在解析string到date的時候出問題,應將sql語句改為:
select part_dt, sum(price) as total_selled, count(distinct seller_id) as sellers from kylin_sales where part_dt between '2014-01-01' and '2014-01-01' group by part_dt -- or select part_dt, sum(price) as total_selled, count(distinct seller_id) as sellers from kylin_sales where part_dt = date '2014-01-01' group by part_dt
上面查詢只用到了fact table,而沒有用到lookup table。如果查詢各個時間段所有二級商品類型的銷售額,則需要fact table與lookup table做inner join:
select fact.part_dt, lookup.CATEG_LVL2_NAME, count(distinct seller_id) as sellers from kylin_sales fact inner join KYLIN_CATEGORY_GROUPINGS lookup on fact.LEAF_CATEG_ID = lookup.LEAF_CATEG_ID and fact.LSTG_SITE_ID = lookup.SITE_ID group by fact.part_dt, lookup.CATEG_LVL2_NAME order by fact.part_dt desc
4. 參考資料
[1] 韓家煒,《數據挖掘——概念與技術》.
[2] 教練_我要踢球, OLAP引擎——Kylin介紹.
[3] Kylin, Design Cube in Kylin.