資料立方體簡介

星際行者發表於2018-05-05

假定我們有一個電商的銷售資料集,其中包括時間、產品、地區、三個維度以及銷售額這個度量資料。其中,各維度表構成如下:

  • 時間維度:時間KEY(time_key)、日期(day)、月(month)、季度(quarter)、年(year)
  • 產品維度:產品KEY(product_key)、產品名稱(product_name)、品牌(brand)、產品類別(product_type)
  • 地區維度:地區KEY(location_key)、城市(city)、省(province)、國家(sumry)

事實表構成如下:

  • 事實表: 銷售額(sales)、時間KEY(time_key)、產品KEY(product_key)、地區KEY(location_key)

人們很形象的將這種基於維度-事實建模方法得到的資料模型成為星型結構。基於這種結構,我們可以使用SQL分組從不同維度進行資料查詢、分析,比如查詢2017年每個月份的銷售額:

select
    t2.month,
    sum(t1.sales) 
from 
    sales_fact t1,
    time_dim t2 
where 
    t1.time_key = t2.time_key and t2.year = `2017`
group by t2.month

從這個例子中可以看到,在進行查詢時需要進行表連線(join)、聚合等比較耗時的操作。為了解決表連線耗時的問題,工程上又提出寬表的方法,也就是接受資料冗餘將維度表與事實表合併成一張表,以犧牲空間代價換取時間代價。但是,這仍然沒有解決聚合耗時的問題,即使使用spark sql、persto這些新一代的記憶體計算計算,在資料量達到一定規模的時候,整個查詢的耗時也將是分鐘級別的,運氣好的話,喝完一杯咖啡可以看到查詢結果。慢查詢會導致整個叢集處於高負載下執行、降低叢集的整體處理速度,在資料量日益增大的今天顯然也是不能接受的。解決查詢低效的一個方法是進行預聚合,按照不同維度進行預先聚合,查詢時直接查詢聚合結果。具體實現上有兩種方法:ROLAP、MOLAP。

ROLAP
ROLAP簡單來說就是用表的方式來儲存按不同維度預先聚合好的資料,比如:

insert into agg_sales_fact_2017(month, sales) from 
select
    t2.month as month, 
    sum(t1.sales) as sales
from 
    sales_fact t1,
    time_dim t2 
where 
    t1.time_key = t2.time_key and t2.year = `2017`
group by t2.month 

當應用程式發起對sales_fact查詢時,通常由一個引擎將基於sql語句轉換為對聚合表的操作:

-- 應用程式發出的SQL語句
select
    t2.month,
    sum(t1.sales) 
from 
    sales_fact t1,
    time_dim t2 
where 
    t1.time_key = t2.time_key and t2.year = `2017`
group by t2.month

-- 引擎轉換後的SQL語句
select 
    month, 
    sales
from 
    agg_sales_fact_2017

顯示如果查詢條件不帶有t2.year = `2017`這樣的維度查詢條件時,整個查詢將退化為對sales_fact、time_dim兩個表的關聯查詢操作,因此需要從設計上加以避免。Mondrian是一個開源的多維查詢引擎,可以將MDX查詢語句轉為相應的SQL語句,MDX是微軟設計的一種類SQL查詢語言

MOLAP
MOLAP是一種不同於資料庫中表的儲存結構,將資料儲存在一種稱為多維立方體的資料結構中。Apache Kylin是最近比較流行的一個MOLAP儲存模型,可以將資料從Hive匯入Kylin中進行儲存,應用程式通過標準的SQL語句查詢Kylin,Kylin具有極高的訪問效能,自從開源以來一直熱度不減。關於MOLAP,韓佳煒教授的《資料探勘概念與技術》一書中有詳細介紹,有興趣可進一步學習。


參考
[1]: What_are_aggregates Mondrian Documentation
[2]: 資料聚集技術在mondrian中的實現
[3]: OLAP引擎Mondrian的學習
[4]: Mondrian ROLAP 小結
[5]: 資料立方體

相關文章