摘要:多維數組多維數組用維和度量的組合表示。此外,還能對多維數據進行深加工。選定多維數組的一個維成員做數據分割的操作稱為該維上的一個切片。
OLAP
為了滿足業務管理和決策的報表系統(包括傳統報表、數據倉庫、OLAP等)也被創建出來,企業主管通過報表了解企業的總體運行狀態。
但是,隨著企業間競爭的加劇和市場節奏的進一步加快,企業的日常管理需要對關鍵業務指標的更加實時的監控和反饋。比如:制造業需要更及時的倉庫調度、金融業需要更實時的風險防范、電信業需要更及時的服務指標監控。于是,越來越多的企業提出實時企業的要求,傳統的ERP等信息系統和報表系統無法滿足這些需求。實時業務監控解決方案旨在更好支撐客戶此類需求。
http://www.tuicool.com/articl...
當今的數據處理大致可以分成兩大類:聯機事務處理OLTP(on-line transaction processing)、聯機分析處理OLAP(On-Line Analytical Processing)。OLTP是傳統的關系型數據庫的主要應用,主要是基本的、日常的事務處理,例如銀行交易。OLAP是數據倉庫系統的主要應用,支持復雜的分析操作,側重決策支持,并且提供直觀易懂的查詢結果。
OLAP技術非常多的特性,概括起來主要有如下幾點特性:
OLAP技術是面向分析人員、管理人員的;
OLAP技術對數據訪問通常是只讀的,并且一次訪問大量數據;
OLAP技術是面向主題的多維數據分析技術。
OLAP(On-Line Analysis Processing)在線分析處理是一種共享多維信息的快速分析技術;
OLAP利用多維數據庫技術使用戶從不同角度觀察數據;OLAP用于支持復雜的分析操作,側重于對管理人員的決策支持,可以滿足分析人員快速、靈活地進行大數據復量的復雜查詢的要求,并且以一種直觀、易懂的形式呈現查詢結果,輔助決策。
上面是OLAP的一些不同的解釋,本文將從以下幾個方面介紹OLAP。
http://www.huqiwen.com/2012/0...
Cube立方體的概念:
在Bi領域,cube是一個非常重要的概念,是多維立方體的簡稱,主要是用于支持聯機分析應用(OLAP),為企業決策提供支持。Cube就像一個坐標系,每一個Dimension代表一個坐標系,要想得到一個一個點,就必須在每一個坐標軸上取得一個值,而這個點就是Cube中的Cell。
Cube是聯機分析的關鍵。他們是一種多維結構,包含原始事實數據、聚合數據,這些數據聚合允許用戶快速進行復雜的查詢,Mdx語言就應用它更是如魚得水。
Cube包含兩個基本概念:維度和度量
維度(Dimension):維度提供了分類描述,表示一類分析角度,用戶通過維度分析度量數據。比如上圖中的三個維度:時間、產品、地域
度量(Measures):度量表示用來聚合分析的數字信息,度量的集合組合成了一個特殊的維度。如數量、銷售額等。
級別(Level):一個維度上可以包含的層次結構,表示特定的分類。如上圖中地域維度可以包含的級別層次級:國家、省、市;時間維度包含的級別層次包含:年、季度、月、日等。
成員,是最重要的概念之一,一個成員是維度(包括度量
計算成員,是一種運行通過特殊表示式動態計算的成員。也就形成了度量(Measures)的結果。計算成員不影響現有的Cube數據,它基于cube數據,通過各種數學表達式和各種函數定義,可以創建復雜的表達式。任何動態分析功能,都可以通過計算成員實現,比如實現占比,同期比等等。
維度的概念
例如一個維度(Dimension):Region
該維度下有四個級別(Levels):country、province、city、county,他們屬于層次集合(Hierarchy)
通過維度和級別我們可以定義一個元素(Member)如:
Region.Levels(1).members(2)=china
Region.Levels(2).members(3)=shanghai
http://www.cnblogs.com/zhijia...
二、 OLAP的基本概念
(1)度量、指標)
是數據度量的指標,是數據的實際意義,即描述數據“是什么”。像上面示例中的人數。
(2)維度
維度是描述與業務主題相關的一組屬性,單個屬性或屬性集合可以構成一個維。如上面示例中的學歷、民族、性別等都是維度。
(3)維的層次
一個維往往可以具有多個層次,例如時間維度分為年、季度、月和日等層次,地區維可以是國家、地區、省、市等層次。這里的層次表示數據細化程度,對應概念分層。后面介紹的上鉆操作就是由低層概念映射到高層概念。概念分層可除根據概念的全序和偏序關系確定外,還可以通過對數據進行離散化和分組實現。
(4)維的成員
若維是多層次的,則不同的層次的取值構成一個維成員。部分維層次同樣可以構成維成員,例如“某年某季度”、“某季某月”等都可以是時間維的成員。
(5)多維數組
多維數組用維和度量的組合表示。一個多維數組可以表示為(維1,維2,……,維n,變量),例如(部門,職系、民族、性別,人數)組成一個多維數組。
(6)數據單元(單元格)
多維數組的取值。當多維數組中每個維都有確定的取值時,就唯一確定一個變量的值。數據單元可以表示為(維1成員,維2成員,……,維N成員,變量的值),例如(人事教育部,技能,回族,男,1人)表示一個數據單元,表示人事教育部職系是技能的回族男性有1人。
(7)事實
事實是不同維度在某一取值下的度量,例如上述人事教育部職系是技能的回族男性有1人就表示在部門、職系、民族、性別四個維度上企業人數的事實度量,并且在為人數事實中包含部門維度人事教育部這一個維度層次,如果將人數事實的所有維度考慮在內,就構成有關人數的多維分析立方體。
三、 OLAP的特點
電子數據表與OLAP相比,不具備OLAP的多維性、層次、維度計算以及結構與視圖分離等特點。
多維。維是OLAP的核心概念,多維性是OLAP的關鍵屬性,這與數據倉庫的多維數據組織正好相互補充。為了使用戶能夠從多個維度、多個數據粒度查看數據,了解數據蘊含的信息,
系統需要提供對數據的多維分析功能,包括切片、旋轉和鉆取等多種操作
四、 OLAP的操作
OLAP比較常用的操作包括對多維數據的切片與切塊、上鉆(drill-up)與下鉆(drill-down)以下旋轉(rotate)等。此外,OLAP還能對多維數據進行深加工。
OALP的這些操作使用戶能夠從多個視角觀察數據,并以圖形、報表等多種形式展示,從而獲取隱藏在數據中的信息。
(1)切片與切塊。
選定多維數組的一個維成員做數據分割的操作稱為該維上的一個切片。通常把多維數組中選定一個二維子集的操作視為切片,假設選定的維i上的某個維成員Vi,則此多維數組子集可以定義為(維V1……,維Vi,維N,變量)。當某維只取一個維成員時,便得到一個切片,而切塊則是某一維取值范圍下的多個切片的疊合。通過對數據立方體的切片或切塊分割,可以從不同的視角得到各種數據。
(2)鉆取
鉆取包括上鉆和下鉆。爭取能夠幫助用戶獲得更多的細節性數據,逐層的分析問題的所在和原因。
上鉆又稱為上卷(roll-up)。上鉆操作是指通過一個維的概念分層向上攀升或者通過維歸約在數據立方體上進行數據匯總。例如在上面的示例中,可以按學歷匯總數據,如把各種學歷的都歸約為所有學歷,便可以得到沿學歷維上鉆的數據匯總。
下鉆是上鉆的逆操作,通過對某一匯總數據進行維層次的細分(沿維的概念分層向下)分析數據。下鉆使用用戶對數據能夠獲得更深入的了解,更容易發現問題本質,從而做出正確的決策。
鉆取使用戶不會再被海量的數據搞得暈頭轉向:上鉆讓用戶站在更高層次觀察數據,下鉆則可以細化到用戶所判決的詳細數據。鉆取的嘗試與維度與維所劃分的層次相對應,根據用戶關心的數據粒度合理劃分。
(3)旋轉
旋轉又稱轉軸,是一種視圖操作,通過旋轉變換一個報告或頁面顯示的維度方向,在表格中重新安排維的位置,例如行列轉換。這種對立方體的重定位可以得到不同視角的信息。
(4)其他OLAP操作
除以上常用多維操作外,還有其他多維操作。
鉆過(drill-across)。鉆過操作涉及多個事實表的查詢并把結果合并為單個數據集,一個典型的例子就是預測數據與當前數據的結合:通常預測數據與當前數據存在于不同的表中,當用戶比較預測銷售與當月銷售時,需要跨多個事實表查詢。
鉆透(drill-through)。鉆透使用關系SQL,查詢數據立方體的底層,一直到后羰的關系表。
五、 OLAP的分類
OLAP分類
按處理方式分類
Server OLAP:絕大多數的OLAP系統都屬于此類,Server OLAP在服務端的數據庫上建立多維數據立方體,由服務端提供多維分析,并把最終結果呈現給用戶
Client OLAP:所相關立方體數據下載一本地,由本地為用戶提供多維分析,從而保證在網絡故障時仍然能正常工作。
按存儲方式分類
ROLAP。ROLAP使用關系數據庫或擴充關系數據庫(XRDBMS)存儲管理數據倉庫,以關系表存儲多維數據,有較強的可伸縮性。其中維數據存儲在維表中,而事實數據和維ID則存儲在事實表中,維表和事實表通過主外鍵關聯。
MOLAP。MOLAP支持數據的多維視圖,采用多維數據組存儲數據,它把維映射到多維數組的下標或下標的范圍,而事實數據存儲在數組單元中,從而實現了多維視圖到數組的映射,形成了立方體的結構。大容量的數據使立方體稀疏化,此時需要稀疏矩陣壓縮技術處理,由于MOLAP是從物理上實現,故又稱為物理OLAP(Physical OLAP)。
DOLAP。DOLAP是屬于單層架構,它是基于桌面的客戶端OLAP,主要特點是由服務器生成請求數據相關的立方體并下載到本地,由本地提供數據結構與報表格式重組,為用戶提供多維分析,此時無需任何的網絡連接,靈活的存儲方式方便了移動用戶的需求,但支持數據有限,使用范圍有限。
~/Desktop/Mondrian數據分析學習.pdf
http://mondrian.pentaho.com/d...
http://www.cnblogs.com/panfen...
在Mondrian里面的cube是以XML的形式定義的。(MDX)
Mondrian本身是不存儲數據的,通過MDX語句(一個類似于SQL的查詢語言)來獲取數據,Mondrian 運行的時候要連數據庫,并且還要有一個數據模型配置文件(Mondrian叫schema),其實就是一個取數據的規則;由此可知Mondrian只不過是把MDX 翻譯成了SQL然后從數據庫中把數據拿出來給用戶
Mondrian是一個開放源代碼的Rolap服務器,使用java開發的。它實現了xmla和jolap規范,而且自定義了一種使用mdx語言的客戶端接口。Mondrian是olap服務器,而不是數據倉庫服務器,因此Mondrian的元數據主要包括olap建模的元數據,不包括從外部數據源到數據庫轉換的元數據。也就是說Mondria的元數據僅僅包括了多維邏輯模型,從關系型數據庫到多維邏輯模型的映射,存取權限等信息。在功能上,Mondrian支持共享維和成員計算,支持星型模型和雪花模型的功能。
Mondrian 是一個開源項目,是開源項目Pentaho的一部分,是一個用Java寫成的OLAP引擎。它實現了MDX語言、XML解析、JOLAP規范。
它從RDBMS和其它數據源讀取數據并把數據聚集在內存緩存中,然后經過Java API用多維的方式對結果進行展示,同時可以不寫SQL就能分析存儲于SQL 數據庫的龐大數據集,可以封裝JDBC數據源并把數據以多維的方式展現出來。
整體的項目架構,四個大部分Schema manager、Session Manager、Dimension Manager、Aggregate Manager
? Schema Manager:與初始化緊密相關。主要是一些重要的數據結構如緩存池的構建以及多維模型的生成。
? Session Manager:最為重要的一個部分。接受MDX查詢、解析MDX,返回結果。
? Aggregate Manager:實現了對聚集表的管理。主要是對OLAP緩存的管理,屬于性能優化的部分。
? Dimension Manager:維度的管理。實現多維模型中維度和關系數據庫表中列的映射,在Schema Manager也有部分功能處理這些映射。
Mondrian通過Schema來定義一個多維數據庫,它是一個邏輯概念上的模型,其中包含Cube(立方體)、Dimension(維度)、Hierarchy(層次)、Level(級別)、Measure(度量),這些被映射到數據庫物理模型。Mondrian中Schema是以XML文件的形式定義的。
Cube(立方體)由維度構建出來的多維空間,是一系列Dimension和Measure的集合區域,它們共用一個事實表。
Dimension(維度)觀察數據的一種角度,維度可以理解為立方體的一個軸。是一個Hierarchy的集合,維度一般有其相對應的維度表,它由Hierarchy(層次)組成,而Hierarchy(層次)又是由組成Level(級別)的。
Hierarchy(層次)是指定維度的層級關系的,如果沒有指定,默認Hierarchy里面裝的是來自立方體中的真實表。
Level(級別)是Hierarchy的組成部分,使用它可以構成一個結構樹,Level的先后順序決定了Level在結構樹上的位置,最頂層的 Level 位于樹的第一級,依次類推。
Measure(度量)是我們要進行度量計算的數值,支持的操作有sum、count、avg、distinct-count、max、min等。
在多維分析中,關注的內容通常被稱為度量(Measure),而把限制條件稱為維度(Dimension)。
多維分析就是對同時滿足多種限制條件的所有度量值做匯總統計。包含度量值的表被稱為事實表(Fact Table),描述維度具體信息的表被稱為維表(Dimension Table)
? 立方體:由維度構建出來的多維空間,包含了所有要分析的基礎數據,所有的聚合數據操作都在立方體上進行。
? 維度:就是觀察數據的一種角度。在這個例子中,路線,源,時間都是維度,
? 維度成員:構成維度的基本單位。對于時間維,例如它的成員分別是:第一季度、第二季度、第三季度、第四季度。
? 層次:維度的層次結構,要注意的是存在兩種層次:自然層次和用戶自定義層次。對于時間維而言,(年、月、日)是它的一個層次,(年、季度、月)是它的另一個層次,一個維可以有多個層次,層次可以理解為單位數據聚合的一種路徑。
? 級別:級別組成層次。對于時間維的一個層次(年、月、日)而言,年是一個級別,月是一個級別,日是一個級別,顯然這些級別是有父子關系的。
? 度量值:要分析展示的數據,即指標。如圖1中一個cell中包含了兩個度量值:裝箱數和截至時間,可以對其進行多維分析。
? 事實表:存放度量值的表,同時存放了維表的外鍵。所有的分析用的數據最終都是來自與事實表。
? 維表:一個維度對應一個或者多個維表。一個維度對應一個維表時數據的組織方式就是采用的星型模式,對應多個維表時就是采用雪花模式。雪花模式是對星型模式的規范化。簡言之,維表是對維度的描述。
? MDX查詢:多維模型的查詢語言MDX(MDX是微軟發布的多維查詢語言標準),它的語法與SQL有很多相似之處:select {[Measures].[Salary]} on columns, {[Employee].[employeeId].members} on rows from CubeTest對于這條語句,COLUMNS 和 ROWS都代表查詢軸,其中COLUMNS代表列軸,ROWS代表行軸。COLUMNS又可以寫成0,ROWS又可以寫成1,當只有兩個查詢軸時,可以理解為結果的展現格式是一個平坦二維表。這條語句的含義就是查詢名字為CubeTest的立方體,列顯示Measures維度的salary,行顯示 Employee維度employeeId級別的所有成員,那么得出的結果就是employeeId所有成員的salary,也就是所有員工的薪酬。具體語法規范和幫助文檔可以參考微軟的用戶文檔。
百萬級事實數據:按照Mondrian文檔中所描述的內容可以看出,只基于操作系統環境和數據庫環境的優化,Mondrian Server在百萬行級別數據量的事實表(關系數據庫)仍能夠運行良好。當然這需要我們自己來評測和證實。
千萬級事實數據:當事實表數據立方體的數據量達到千萬行以上時,Mondrian建議采用“匯總表”或者是由數據庫支持的類似Oracle數據庫的“物化視圖”功能來優化OLAP查詢的性能。
Mondrian緩存設置:由于Mondrian會將查詢過的數據緩存起來,所以Mondrian建議緩存的大小根據具體項目的實際情況判斷,當然是緩存越大越好
為了提高海量數據下的查詢響應速度,Mondrian自動將首次查詢的結果緩存到內存中,之后的查詢如果命中緩存內容,則不再訪問數據庫。這種實現方式有點自不必說,
但是在實現實時OLAP時會存在問題,實時OLAP中數據變化頻繁導致緩存中的數據不是最新的。
緩存控制接口:為了做到不重啟OLAP Server也能更新緩存,Mondrian提供了一系列的刷新緩存的接口,支持指定清除指定schema的元數據緩存、查詢結果緩存;清除動作可以是全部清除 也可以是 部分清除(可以指定清除某個維度下某級別成員的相關內容)。
數據變化監聽: Mondrian提供了緩存控制接口(被動響應),但對于實現我們的目標“實時OLAP”來說我們就需要自己實現一個數據變更監聽的模塊,來監聽數據變化,一旦數據有變化就發起變更事件,更新Mondrian引擎的緩存。目前初步考慮實現方案為ETL工具在數據處理結束后通知OLAP引擎。引擎收到數據變更通知后做清理緩存的動作。
Jpivot:簡單說是一個展示工具,有人說是個標簽庫,類似于struts。只是用來顯示mondrian傳來的xml數據,將其渲染成我們熟悉的html。對于層次性很強的報表,XML渲染的確有他的魅力,免去了繁雜的js痛苦??傊甿ondrian是用來研究和提取數據,jpivot是用來顯示數據。至于jpivit是如何顯示數據,主要是通過xls+xml。 Jpivot本身的界面是很難看的。
Pentaho、Saiku、Jpivot都用到了Mondrian做為其多維數據處理的服務器,網上的很多關于Mondrian的文章也都是以Jpivot來進行分析的,
不過Jpivot已經被拋棄了作者也不再更新了,并且Jpivot只能支持到Mondrian3.5 所以對于新版本的Mondrian一定是不能用Jpivot了(不過Jpivot有一個替代品Pivot4j這個還在持續維護),
這里還是推薦大家用Saiku或者Pivot4j
如果我們不想用Saiku、pivot4j 這樣現成的東西(畢竟有很多東西我們用不到)那么可以把Mondrian 集成到我們自己的應用中去
http://mondrian.pentaho.com/d...
personDemo.xml
對應表:
CREATE TABLE `person` ( `userid` varchar(100) , `department` varchar(100) , `username` varchar(100), `sex` varchar(100) , `nationality` varchar(100), `post` varchar(100), `zyjslb` varchar(100), `zyjsdj` varchar(100) , `zhixi` varchar(100), `xueli` varchar(100) , `age` int(10) , PRIMARY KEY (`userid`) )
MDX查詢語句:select NON EMPTY {[Measures].[人數]} on columns, NON EMPTY {([部門].[所有部門], [職系].[所有職系], [專業技術資格類別].[所有專業技術資格類別], [專業技術資格等級].[所有專業技術資格等級], [學歷].[所有學歷], [民族].[所有民族], [性別].[所有性別])} ON rows from Person
模型配置文件XML元素分析http://www.biaodianfu.com/ola...
Schema
Schema 定義了一個多維數據庫。包含了一個邏輯模型,而這個邏輯模型的目的是為了書寫 MDX 語言的查詢語句。這個邏輯模型實際上提供了這幾個概念:
Cubes: 立方體
Dimensions: 維度
Hierarchies: 層次
Levels: 級別
Members: 成員
而一個schema 文件就是編輯這個 schema 的一個xml 文件。在這個文件中形成邏輯模型和數據庫物理模型的對應。
Cube
一個 Cube 是一系列維度 (Dimension) 和度量 (Measure) 的集合區域。在 Cube 中, Dimension 和 Measure 的共同地方就是共用一個事實表。 Cube 中的有以下幾個屬性:
name: Cube 的名字。
caption: 標題 , 在表示層顯示的。
cache: 是否對 Cube 對應的實表用 mondrian 進行存儲 , 默認為 true。
enabled: 是布爾型的 , 如果是被激活 ,Cubes 就執行 , 否則就不予理睬,默認為 true。
Cube 里面有一個全局的標簽定義了所用的事實表的表名。
Dimension
他是一個層次( Hierarchies )的集合 , 維度一般有其相對應的維度表 . 他的組成是由層次(Hierarchies)而層次(Hierarchies)又是有級別(Level)組成 . 其屬性如下:
name: Dimension 的名稱。
type: 類型,有兩個可選的類型: StandarDimension 和 TimeDimension ,默認為StandardDimension。
caption: 標題 , 在表示層顯示的UsagePrefix加前綴 , 消除歧義。
foreignKey: 外鍵,對應事實表中的一個列,它通過
Hierarchy
你一定要指定其中的各種關系,如果沒有指定,就默認 Hierarchy 里面裝的是來自立方體中的真實表 . 屬性如下:
name: Hierarchy 的名稱,該值可以為空,為空時表示 Hirearchy 的名字和 Dimension 的名字相同。當一個 Dimension 有多個 Hierarchy時,注意 name 值要唯一。
hasAll: 布爾型的 , 決定是否包含全部的成員 member。
allMemberName: 所有成員的名字 , 也就是總的標題 , 例如: allMemberName= “全部產品”。
allLevelName: 所有級別的名字,它會覆蓋其下所有的 Member 的 name 和所有的 Level 的 name 屬性的值。
allMemberCaption: 例如 : allMemberCaption= “全部產品”這個是在表示層顯示的內容。
PrimaryKey: 通過主鍵來確定成員,該主鍵指的是成員表中的主鍵,該主鍵同時要與 Dimension 里設置的 foreignKey 屬性對應的字段形成外鍵對應關系。
primaryKeyTable: 如果成員表不只一個,而是多個表通過 join 關系形成的,那么就要通過這個屬性來指明 join 的這些表中,哪一個與Dimension 里設置的foreignKey 屬性形成外鍵關系。通過該屬性來指明主表。
caption: 標題 , 在表示層顯示的。
defaultMember
memberReaderClass 設定一個成員讀取器,默認情況下 Hierarchy 都是從關系型數據庫里讀取的,如果你的數據不在 RDBMS 里面的話,你可以通過自定義一個member reader 來表現一個 Hierarchy 。
Level
級別 , 他是組成 Hierarchy 的部分。屬性很多,并且是 schema 編寫的關鍵,使用它可以構成一個結構樹, Level 的先后順序決定了 Level在這棵樹上的的位置,最頂層的 Level 位于樹的第一級,依次類推。 Level 的屬性如下:
name: 名稱
table: 該 Level 要使用的表名
column: 用上面指定的表中某一列作為該 Level 的關鍵字
nameColumn: 用來顯示的時候使用,如果不定義,那么就采用上面的 column 的值來進行顯示。
oridinalColumn: 定義該 Level 上的成員的顯示順序,如果不指定,那么采用 column 的值。
parentColumn: 在一個有父 – 子關系的 Hierarchy 當中,當前 Level 引用的是其父成員的列名。好比是一張部門表,在一張表里表現部門的上下級關系,一個是主鍵,肯定還有一個字段為連接到該主鍵的外鍵的列名,這里的 parentColumn 指的就是這個列名。
nullParentValue: 如果當前的 Level 是有上下級關系(設置了 parentColumn 屬性),如果該 Level 又處于頂級,我們需要將頂級的數據取出來,這里指的是位于頂級的父成員的值,有些數據庫不支持 null, 那么也可以使用0或-1 等,這就表示頂級的成員的父 ID 為0 或為-1 。
type: 數據類型,默認值為 string 。當然還可以是 Numeric 、 Integer 、 Boolean 、 Date 等。
uniqueMembers: 該屬性用于優化產生的 SQL ,如果你知道這個級別和其父級別交叉后的值或者是維度表中給定的級別所有的值是唯一的,那么就可以設置該值為 true ,否則為 false 。
levelType: 該 Level 的類型,默認為 regular (正常的),如果你在其 Dimension 屬性 type 里選擇了 TimeDimension 那么這里就可以選擇 TimeYears 、 TimeQuarters 、 TimeMonth 、 TimeWeeds 、 TimeDays 。
hideMemberIf: 在什么時候不隱藏該成員,可選的值有三個: Never 、 IfBlankName 、 IfParentName
approxRowCount: 該屬性可以用來提高性能,可以通過指定一個數值以減少判斷級別、層次、維度基數的時間,該屬性在通過使用 XMLA 連接Mondrian 很有用處。
caption: 標題 , 在表示層顯示的。
captionColumn: 用來顯示標題的列。
formatter: 該屬性定義了 Member.getCaption() 方法返回的動作值,這里需要是一個實現了 mondrian.olap.MemberFormatter 接口的類,用來對Caption地值進行格式化。
Join
對于一個 Hierarchy 來說,有兩種方式為其指定:一種是直接通過一個 Table 標簽指定;一種是通過 Join 將若干張表連接起來指定。一旦采用 Join 的話,那么就要在 Hierarchy 里的 primaryKeyTable 屬性指定主表。
Measure
Measure 就是我們要計算的數值,操作的核心。它的屬性如下:
name: 名稱。
aggregator: 要采用的計算函數。
column: 要計算的列名。
formatString: 計算結果的顯示格式。
visible: 是否可見。
datatype: 數據類型,默認為 Numeric
formatter: 采用類來對該 Measure 的值進行格式,具體參考 Level 的 formatter 屬性。
caption: 標題,用來顯示時使用。
概括總結一下:在多維分析中,關注的內容通常被稱為度量(Measure),而把限制條件稱為維度(Dimension)。多維分析就是對同時滿足多種限制條件的所有度量值做匯總統計。包含度量值的表被稱為事實表(Fact Table),描述維度具體信息的表被稱為維表(Dimension Table),同時有一點需要注意:并不是所有的維度都要有維表,對于取值簡單的維度,可以直接使用事實表中的一列作為維度展示。
下描述了一個數據庫的結構。該數據庫中共有五張表,分別是Sales表,Customer表,Time表,Product表和Mfr表。這個數據庫的作用是存儲每一筆交易:包括這筆交易發生在什么時間,交易的產品類型,進行交易的客戶信息,交易方式,交易了多少件產品以及成交金額是多少。
模型中有一張事實表(Sales),兩個度量列(units和dollars),四個維度表(Product, Mfr, Customer, Time)。在這個星型模型的最頂層,我們創建了以下多維模型:
[Sales]立方體包含[Unit sales]和[Dollar sales]兩個度量值;
[Product]維度包含[All Products],[Manufacturer],[Brand],[Prodid]四個級別;
[Time]維度包含[All Time],[Year],[Quarter],[Month],[Day]五個級別;
[Customer]維度包含[All Customers],[State],[City],[Custid]四個級別;
[Payment Method]維度包含[All Payment Methods],[Payment Method]兩個級別。
假設現在我們要對交易做一些統計,例如,某一件特定產品在某一個時間段內以某種特定方式總共賣出多少件或多少錢,這時成交產品數和成交金額是我們最終關注的內容,其他的因素例如時間、產品、方式等都只是對我們最終關注內容進行統計的限制條件。
在上面的例子中,限制條件有時間、產品類型、用戶類型和交易方式,
有時我們并不需要同時使用所有的限制條件,例如,當我們只想知道指定產品的成交總金額時,那么除了產品類型之外其他三個限制條件都是多余的,而在查詢時,需要在整個事實表中執行查詢,找出產品類型為指定類型的所有產品然后再做統計,為了提高查詢效率,我們可以新建一張表,這張表按照產品類型把事實表中的行合并到一起,合并的方式是拋棄其他維,把度量值按特定的方式(max,min,sum,count或avg)整合到一起。這種表被叫做聚合表(Aggregate Table)。
聚合表的應用場景
事實表中的行構成了一個集合,每一維(或若干維)按照其取值的不同可以將事實表這個全集劃分成若干個不相交的子集。聚合表所做的工作實際上就是把劃分出的子集歸為數據庫表中的一行,這樣做一方面可以減少數據庫表的行數,另一方面也省去了查詢時所需要做的一些統計工作,從而提高查詢時的效率。
使用Mondrian做大數據量(如>100W行)的OLAP分析時,考慮是否可以使用聚合表進行優化。
然而Mondrian的優化方式又不限于聚合表這一種,是否要進行聚合表優化,要根據實際情況來決定。
Mondrian目前并不提供對聚合表的數據同步機制,如果要做實時OLAP,需要自己實現聚合表和事實表中的數據同步。
聚合表的定義見:http://www.cnblogs.com/panfen...
http://sourceforge.net/projec...
http://blog.csdn.net/athenaer...
其他參考:http://blog.csdn.net/zhangzho...
http://blog.csdn.net/xiaolang...
http://wushexu.iteye.com/blog...
MDX(Multidimensional Expressions)是多維 數據庫(OLAP 數據庫)的查詢語言.
Mondrian是java中的一個OLAP與MDX解析引擎,它會解析MDX,轉換成SQL來查詢關系數據庫(可能是多條查詢)。
MDX 的內容很多,功能強大,這里只介紹最基礎和最重要的部分。
以下是里兩條MDX 查詢語句及其查詢結果
? 語句1:
SELECT { [Measures].[Dollar Sales], [Measures].[Unit Sales] } on columns, { [Time].[Q1, 2005], [Time].[Q2, 2005] } on rows FROM [Sales] WHERE ([Customer].[MA])
語句 2
SELECT { [Time].[Q1, 2005], [Time].[Q2, 2005], [Time].[Q3, 2005] } on columns, { [Customer].[MA], [Customer].[CT] } on rows FROM Sales WHERE ( [Measures].[Dollar Sales] )
第一條語句查詢對[Customer].[MA]這個客戶在 2005 年第一、第二季度的銷售額、報表期銷售額。
第二條語句查詢對[Customer].[MA], [Customer].[CT]這兩個客戶在 2005 年前三個季度的銷售額。
可以看到,mdx 有類似 sql 的結構,同樣有 select、from、where 這三部分。但也有很多不同。
Select 字句指定一個集合,把它放到某個軸上。
From 字句說明要從哪個數據立方體來查詢。
方括號([])用于維度名、層次名、維度成員名,避免名字和函數混淆(函數名
是不加方括號的)。
Where 字句指定切片,即對不出現在軸上的維度的成員的限定。
Mdx 沒有 group by 字句。其實分組是隱含的。
Mdx 沒有 order by 字句。排序只會對某個軸進行,通過使用排序函數。
和 sql 一樣,mdx 也是不區分大小寫的,并且可以隨意分行。
Mdx 中也可以包含注釋,除了支持 sql 的--注釋外還支持//和/ ... /注釋。
2 軸用 on {axis}語法來把維度分配到軸(Axis,復數 Axes)上,一個查詢可以有多個軸。
不同軸用逗號分隔,分配的順序是沒關系的。但如果把軸調換(如 A on columns, B on rows 改成 A on rows, B on columns),結果的行和列也會轉置過來。
軸用 axis(0),axis(1),axis(2)...表示,前五個軸可以使用別名 Columns,Rows,Pages,Chapters,Sections。因此 on Columns 等價于 on axis(0)。超過 5 個軸時只能用 axis(5),axis(6)...來表示(極少會需要這么多的軸)。
很多實現(包括 Mondrian)支持僅用數字表示軸,因此 on Columns 可以寫成 on 0。axis(0)和別名表示可以混用,例如下面語句是可以的:
SELECT { [Time].[Q1, 2005], [Time].[Q2, 2005] } on axis(0), { [Customer].[MA], [Customer].[CT] } on rows FROM Sales
軸必須從 0 開始,并且連續,不能跳過。下面的是不可以的:
SELECT { [Time].[Q1, 2005], [Time].[Q2, 2005] } on rows, { [Customer].[MA], [Customer].[CT] } on pages FROM Sales
錯誤,跳過了軸 axis(0)(columns) 。
在大多查詢中,軸一般是兩個。一個軸也可以,甚至 0 個軸。
如果軸多于兩個,就沒法在平面上表示。如果維度多于兩個,需要把多個維度(交叉后)放到一個軸上。
切片(Slice)維度就是出現在 MDX 語句 WHERE 子句中的維度,跟 SQL 一樣,表示對數據集的限制。例如 MDX 語句:
SELECT
{[Product].[All Products].[Food], [Product].[All Products].[Drink]} ON COLUMNS
FROM [Sales]
WHERE [Time].[Year].[2005]
限制了查詢的數據范圍,只限于 2005 年。語法和 SQL 不一樣,[Time].[Year].[2005](是一個元組)本身就表示了一個條件。這可以看成對數據立方體從某個方向進行切片(從 Time維度的方向)得到一個子立方體,因此叫切片。
切片維度不會出現在軸上。上面的時間維度不會出現在軸上。
一個維度不能同時出現在軸維度(SELECT 的維度)和切片維度上。
切片器維度只可接受評估為單個元組的表示式
如果一個維度既沒有出現在軸維度上,也沒有出現在切片維度上,就會用維度的(默認層次的)默認成員進行切片。一般維度的默認成員是“All xxx” ,因此默認是對這個維度所有成員的數據進行聚集操作。例如:
SELECT {[Time].[Year].Members } ON COLUMNS
FROM [Sales]
Product 維度沒有出現在軸維度和切片維度上。如果 Product 的默認成員是[All Products],就會查詢所有產品的銷售額匯總,符合人的習慣。上面語句相當于:
SELECT {[Time].[Year].Members } ON COLUMNS
FROM [Sales]
WHERE [Product].[ All Products]
維度有一個函數 defaultMember 可以返回維度的默認成員,因此也相當于:
SELECT {[Time].[Year].Members } ON COLUMNS
FROM [Sales]
WHERE [Product]. defaultMember
除了 Product 維度,其他沒有出現在軸維度和切片維度上的維度也是一樣的。
度量維度(為了一致可以把度量看成一個維度:Measures 維度)是沒有”All xxx”成員的,它的默認成員可以明確設置,如果沒設置,就是第一個度量。如果默認度量是[Store Sales],
下面的查詢
SELECT {[Time].[Year].Members } ON COLUMNS
FROM [Sales]
和
SELECT {[Time].[Year].Members } ON COLUMNS
FROM [Sales]
WHERE [Measures]. [Store Sales]
是等價的。
一個維度的默認成員、是否有 All 成員(一般都應該有),是可以在 Schema 文件中設置的。
如果沒有明確設置默認成員,默認成員就是 All 成員,如果沒有 All 成員,默認成員就是第一個成員。
元組和集合是 MDX 中的兩種數據類型,也是 MDX 語句的構件。
元組元組(Tuple)就是一個或多個維度的成員的組合當一個元組有多個維度時,必須用括號括起來
([Customer].[Chicago, IL], [Time].[Jan, 2005])
一個元組可以代表立方體的一個切片
以這種語法構造的元組可以直接用于
SELECT
{ ( [Time].[2005], [Measures].[Dollar Sales],
( [Time].[Feb, 2005],[Measures].[Unit Sales] )
} ON COLUMNS ,
{ [Product].[Tools], [Product].[Toys]} ON ROWS
FROM [Sales]
元組不能嵌套
元組用于定義來自多維數據切片;他是由一個或多個維度的單個成員的有序集合組成。元組內不包含來自同一個維度的多個成員(可以理解為坐標),元組用()包圍。
where 字句也是一個元組,用以指定一個數據切片
集合(Set)是零個、一個或多個元組的有序集合。不像數學上的集合,MDX 集合一個元組可以出現多次,而且順序是重要的。
集合最常用于在Mdx查詢中定義軸維度和切片器維度, 通常的指定集合的方式是把一個元組列表用花括號括起來。如{ [Customer].[MA],
[Customer].[CT] }就表示一個集合,集合里是客戶維度的兩個成員。一個集合中的所有元組必須有同樣的維度性質,即所表示的維度及其順序。
使用下面的集合將會報錯,因為維度的順序不一樣:
{ ( [Time].[2005], [Measures].[Dollar Sales] ), ( [Measures].[Unit Sales], [Time].[Feb, 2005] ) }
很多函數都可以返回一個集合
要把維度成員放在軸上,可以列舉維度的成員,例如{ [Customer].[MA], [Customer].[CT] }。也可以通過范圍語法或一個函數得到成員的集合。
通過坐標值可以定義出每個成員的名稱
冒號(:)語法可以表示成員范圍。冒號前后是同一個層次的起點和終點兩個成員。
SELECT
{ [Time].[2003] : [Time].[2008] } on columns,
{ [Product].[Drinks] : [Product].[Bread] } on rows
FROM [Sales]
時間維度表示 2003 年到 2008 年(6 個成員),產品維度表示從 Drinks 到 Bread。這通常跟排序方式有關。
集合里可以包含子集合。例如下面集合,包含 2001 年的前三個月跟后三個月。
{ { [Time].[January-2001] : [Time].[March-2001] } ,{ [Time].[October-2001] : [Time].[December-2001] } }
可以用成員名稱或成員鍵引用某個成員。
&符號可以標記出其父級中的元素集合中的值也叫做元素值,&符號用于區分成員鍵和成員名稱。例如:
SELECT {[Dim Region].[City].&[上海],[Dim Region].[City].&[北京]} ON COLUMNS, {[Dim Time].[Day Of Month].&[13],[Dim Time].[Day OfMonth].&[14]} ON ROWS FROM [MKAS] WHERE ([Measures].[Fact Ind Count])全部成員
大多時候需要得到一個維度、層次、層的全部成員,這個時候可以使用.Members 操作(函數)。比如[Time].[Years].Members 可以得到所有年份。
SELECT
{ [Time].[Years].Members} ON COLUMNS,
{ [Product].[Line].Members} ON ROWS
FROM [SteelWheelsSales]
WHERE [Measures].[sales]
這個語句查詢所有年份、所有產品線的銷售額,把年份放在列上,產品線放在行上。
有時候需要得到某個成員的下一層次的全部成員,這是需要用.Children 函數。這在下鉆操作時經常用到。
例如要得到產品線 Classic Cars 下的所有產品,可以這樣[Product].[Line].[Classic
Cars].Children。[Product].[Line].[Classic Cars]是 Product 維度 Line 層的一個成員。
.Children 只能得到直接下級成員,如果需要多級,需要使用 Descendants()函數。語法是:
Descendants (member [, [ level ] [, flag]] )
Descendants 返回 member 成員下 level 層的成員,可選標志 flag 有多個選項,以設置包含最下一層上面的哪些層的成員。
以下是一個例子,查詢 Tools 和 Toys 兩類產品在 2005 年各月的銷售額,因為年和月兩個層次中間有一個季度層次,所以不能用[Time].[2005].Children。
SELECT
{ [Product].[Tools], [Product].[Toys] } ON COLUMNS,
Descendants ([Time].[2005],[Time].[Month],SELF_AND_BEFORE) ON ROWS
FROM Sales
WHERE [Measures].[Dollar Sales]
flag 設為 SELF_AND_BEFORE,可以看到行上包含了 2005 年和各個季度(如果設為SELF 則不會包含) 。
有時要獲取維度成員的屬性(維表上的某些列),這時可以使用 dimemsion properties子句。dimemsion關鍵字可以省略。
以下查詢同時獲取客戶所在地的郵編屬性
SELECT
{ [Customer].[Akron, OH].Children }
DIMENSION PROPERTIES [Customer].[Zip Code]
on columns,
{ [Product].[Category].Members } on rows
FROM Sales
WHERE ([Measures].[Units Sold], [Time].[July 3, 2005])
在多維空間,數據很多時候是稀疏的。比如:比如,不是每一個產品都銷售給了所有的客戶,不是每一個客戶在每個時期都購買了產品。如果按維度所有成員交叉得出報表,就會有很多空行、空列。
要從查詢結果去掉這些空行
SELECT
{ [Time].[Jan,2005],[Time].[Feb,2005] } ON COLUMNS ,
NON EMPTY { [Product].[Toys], [Product].[Toys].Children } ON ROWS
FROM Sales
WHERE ([Measures].[Dollar Sales], [Customer].[TX])
這樣空行就去掉了。non empty 可用于任何軸上。
很多時候,我們需要對兩個不同的集合進行交叉,也就是要得到兩個集合成員的所有組合。CrossJoin()函數就是用來得到組合的最直接方式,它的語法是 CrossJoin (set1, set2)
以下語句在每個季度下分出兩個度量
SELECT
CrossJoin (
{ [Time].[Q1, 2005], [Time].[Q2, 2005]},
{ [Measures].[Dollar Sales], [Measures].[Unit Sales] }
) ON COLUMNS,
{ [Product].[Tools], [Product].[Toys] } ON ROWS
FROM Sales
CrossJoin 的結果是一個集合。因此支持CrossJoin 嵌套。
Filter 函數用來篩選一個集合,它以一個集合和一個 boolean 表達式為參數
Filter (set,boolean-expression)。
例如,以下表達式會返回關聯的產品銷售額至少為500 的產品分類的集合。
Filter (
{ [Product].[Product Category].Members },
[Measures].[Dollar Sales] >= 500
)
要求銷售額至少為 150 并且銷售額要至少在成本的1.2 倍以上
Filter (
{ [Product].[Product Category].Members },
([Measures].[Dollar Sales] >= 1.2 *[Measures].[Dollar Costs])
AND [Measures].[Dollar Sales] >= 150
)
Order()函數用于對一個集合進行排序,語法:
Order (set1, expression[,ASC| DESC | BASC | BDESC])
SELECT
{ [Measures].[Dollar Sales] } on columns,
Order (
[Product].[Product Category].Members,
[Measures].[Dollar Sales],
BDESC
) on rows
FROM [Sales]
WHERE [Time].[2004]
在 sql 中可以增加計算出來的列,MDX 中同樣也可以,在 MDX 中叫計算成員(CalculatedMember)。因為MDX 操作的是多維數據,計算成員實際是給一個維度增加成員。
語法:
with
member 成員標識 as ‘表達式’ [, 屬性...]
select ...
表達式用單引號引注。
以下例子增加一個新的度量[Avg Sales Price]
WITH
MEMBER [Measures].[Avg Sales Price] AS
"[Measures].[Dollar Sales] / [Measures].[Unit Sales]"
SELECT
{ [Measures].[Dollar Sales], [Measures].[Unit Sales],
[Measures].[Avg Sales Price]
} on columns,
{ [Time].[Q1, 2005], [Time].[Q2, 2005] } on rows
FROM Sales
WHERE ([Customer].[MA])
當不止一個維度增加了計算成員時,由于每個維度的成員都有計算公式,在這些維度的交叉點上,就可以有多種計算順序。這時候就不需要考慮公式優先級的問題。因此引入了 SOLVE_ORDER 屬性
WITH
MEMBER [Measures].[Avg Sales Price] AS
‘[Measures].[Dollar Sales] / [Measures].[Unit Sales]",
SOLVE_ORDER=0
MEMBER [Time].[Q1 to Q2 Growth] AS
‘[Time].[Q2, 2005]- [Time].[Q1, 2005]’,
SOLVE_ORDER=1
SELECT
{ [Measures].[Dollar Sales], [Measures].[Unit Sales],
[Measures].[Avg Sales Price]
} on columns,
{ [Time].[Q1, 2005], [Time].[Q2, 2005], [Time].[Q1 to Q2 Growth] } on rows
FROM [Sales]
WHERE ([Customer].[MA])
命名集合(Named Set)允許預先定義的一個集合,供后面的語句使用。語法和計算成員類似。
with
set 集合標識 as ‘集合表達式’
select ...
WITH
SET [User Selection] AS ‘{ [Product].[Action Figures], [Product].[Dolls] }"
MEMBER [Product].[UserTotal] AS ‘Sum ( [User Selection] )’
SELECT
{ [Time].[Jan, 2005], [Time].[Feb, 2005] } ON COLUMNS,
{ [Product].[Toys], [User Selection], [Product].[UserTotal] } ON ROWS
FROM Sales
WHERE ([Measures].[Unit Sales])
http://mondrian.pentaho.com/d...
列出一些重要的,按返回類型來分類。
成員函數.currentMember
.parent
.prevMember/.nextMember
.firstChild/.lastChild
.firstSibling/.lastSibling
Ancestor(
Ancestor(
LAG 返回當前成員開始往前數的本層的第幾個成員.
n是索引,0 是它本身,1是前一個(.prevMember)
LEAD 類似 Lag(),但方向相反
OpeningPeriod 返回某個層次上第一個后代成員
語法:OpeningPeriod([
ClosingPeriod 返回某個層次上最后一個后代成員
PARALLELPERIOD 返回一個成員同層次對應位置的成員
ParallelPeriod([
前面介紹的 members、children、descendants、crossJoin、filter、order 都是集合函數
union
合并兩個集合。語法:Union(set1,set2[, ALL]) All 標志指示保留重復元素
Except
從set1里去除set2的元素,即求兩個集合的差。Except(set1,set2[, ALL])
Head/Tail
返回集合Head/Tail元素 。 Head/Tail(set[,
.SIBLINGS
返回成員的兄弟成員,包括它自己。
.MEMBERS
返回維度/層次的成員。
DESCENDANTS
返回成員的后代成員。Descendants (member, [level[,flag]])
flag 可以是:SELF、BEFORE、SELF_BEFORE_AFTER、LEAVES、AFTER、SELF_AND_BEFORE、SELF_AND_AFTER。
DrillDownLevel(set,[level])
下鉆(一級)成員。
DrillDownLevelBottom(set,index,level)
下鉆最下一級成員。
DrillDownLevelBTop(set,index,level)
下鉆最上一級成員。
DrillDownMember
下鉆集合2中的成員.DrillDownMember(set1,set2[,Recursive])
TopCount 返回前n個數據的集合
TopCount( , , ) TopCount( , )
(TopCount, BottomCount, TopPercent, Hierarchize ,etc.)
統計函數count (set [,INCLUDEEMPTY])
可選標記指定是包含無數據的元組
Sum (set [,數值表達式]])
max/min/median/avg(set [,數值表達式]])
IS
object is object2。
例如:
[Jan 2000].PrevMember IS NULL
[Jan 2000].Level IS [Time].[Month]
ISEMPTY
判斷一個值是否為空。語法:IsEmpey(表達式)。
NAME
返回維度、層次等的名稱。語法:
PROPERTIES
返回成員的屬性值。語法:
這里是一些返回類型不定的函數。
iiF
根據條件返回值,類似Excel 的If 函數。語法:iif(<布爾表達式>, <值1>, <值2>)。
ITEM
根據索引返回集合中元素。語法:item(set,
返回類型一般為元組。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66347.html
閱讀 3772·2021-11-23 09:51
閱讀 4384·2021-11-15 11:37
閱讀 3521·2021-09-02 15:21
閱讀 2745·2021-09-01 10:31
閱讀 878·2021-08-31 14:19
閱讀 851·2021-08-11 11:20
閱讀 3307·2021-07-30 15:30
閱讀 1688·2019-08-30 15:54