從前到現在,用戶需要從IT系統中獲取信息的變化無常與程序員從傳統數據庫中製作報表的代價是一個永恆的矛盾。
這邊廂程序員爲了應付客戶忽然而至的報表需求痛苦不已, 客戶只想要他想知道的東西,不會管查詢語句有多麼複雜,優化從海量數據中提取報表的速度有多麼困難。
那邊廂客戶爲了等程序員做一個報表,快則半天,慢則一週,事情都過去了。明明只想知道一樣很簡單的東西, 程序員卻要抱怨查詢是多麼複雜,數據結構是如何制約。有時候出一個報表要呆在屏幕前等半天。
而OLAP是唯一一種真正讓用戶獲得自己所需要的報表而且不用付出巨大實現代價的方法。它能夠讓用戶自由的定製自己的查詢條件,觀察、累計的維度,最後從海量數據中快速生成它。
方案經過幾年的發展,各大數據庫供應商都有了自己的OLAP方案。不過我們一來不想把產品綁定在某個數據庫上,二來沒錢,所以還是要尋求窮人們自己的免費且底層數據庫通用的方案。
從AgileJava的Blog上,看到了Mondrian + JPivot:
Mondrian蒙德里安,OLAP核心引擎,負責從關係數據庫中計算、緩存數據,響應來自表現層的使用MS家 MDX語法的查詢。這個微軟家的MDX語法,學起來並不難,SQL Server的書也統統有教。
在這一層要做的事情就是定義一個schema元模型,包括 維度(Dimensions), 層次(Hierarchies),級別(Levels),和成員(Members)等。Mondrian要根據它來從關係數據庫中聚合數據響應MDX語法的查詢。
JPivot
OLAP JSP custom tag library。提供OLAP Navigator與多 維數據的顯示,並支持圖表生成和Export to Excel。Mondrian的御用表現層。
初遇
Mondrian用了MS家著名的FoodMart數據作例子,Access作底層數據庫,JPivot做表現層,讓你幾分鐘之內就能把Example跑起來,感受一下OLAP報表是什麼樣子的。跑完一遍之後,我就發現做個客戶自定製的OLAP報表如此簡單.....
如前所說,Mondrian是OLAP的核心引擎,負責從關係數據庫中計算、緩存數據,響應來自表現層的使用MS家 MDX語法的查詢。具體表現形式呢,就是一個jar,隨Tomcat啓動。
看完那個FoodMart的Sample之後, 該自己動手了。
首先第一步是設計OLAP的數據庫結構。
因爲和業務數據庫相比,OLAP需要冗餘一些數據達到更快的查詢。
設計前可以先參拜一下那本經典的《完全維度設計指南》,中文版的幾下就能翻個大概。
其實說白了就是去除與報表無關的列,把訂單、訂單明細兩個表合併成一個銷售事實表,把產品,產品分類兩個表合併成一個產品維表這幾個動作。
設計完之後,應該會有幾個裝有統計數據和維表外鍵的事實表,和幾個用於分類,排序,過濾的維表。
第二步是把業務數據庫裏的數據導過來。
有不少ETL的工具,弄出一大堆映射文件,轉換類來。不過我還是喜歡直接寫SQL快捷,可能我面對的不是一天一個G的數據庫吧。
第三步是把剛纔設計的數據庫結構定義成Schema
schema元模型包括 維度(Dimensions)、層次(Hierarchies)、級別(Levels)、和成員(Members)等。Mondrian要根據它來從關係數據庫中聚合數據響應MDX語法的查詢。
在這一步之前記得先裝一箇中文版的SQL Server2000,裏面的Help文件有詳細的解釋。
另外jprovit有一個子項目,是這個schema的Eclipse Plug-in。即使不用這個Plug-in,有了它的DTD,在其他XML編輯器裏也能避免拼寫錯誤引起的冤枉時間。
用Sample中的FoodMart.xml做藍本,兩下就能Copy Paste出自己的schema來。
最後,注意Oracle的列名必須全大寫。
JPivot 是Mondrian的表現層TagLib,一直保持着良好的開發進度。
已經好久沒有用了,趁徹底忘記以前,把小小的心得記下來。
1.漢化
1.1 查找所有resources.properties文件,漢化爲resources_zh.properties文件
1.2 native2ascii resources_zh.properties resources_zh.properties
1.3 查找WEB-INF/jpivot下的所有xml文件,漢化爲xxx_zh.xml
2.架構
JPivot的架構看似另類,但其實都是精明的選擇。
2.1 使用XML/ XSLT渲染OLAP報表
JPivot 使用 WCF (Web Component Framework) ,基於XML/XSLT來渲染Web UI組件。這使它顯得十分另類。不過,OLAP報表這種非常複雜但又有規律可循的東西,最適合使用XSLT來渲染。雖然程序員和編輯器都很不喜歡這種Martin Flower口中有點LISP形式的語言,但Transform Engine這時候的確能比Template Engine(Velocity,Freemarker)更高效的處理OLAP報表及其導航系統的顯示。
2.2 完全基於JSP+TagLib
JPivot另外一個可能使人不慣的地方是它完全基於taglib而不是大家熟悉的MVC模式。但如果不基於tabLib,基於任何MVC框架都會使其失去通用性,擔不起Mondrain唯一表現層的重任,而且,MVC其實不一定需要那些框架(後述)
2.3 典型的流程及模式:
打開JPivot自帶的sample,查看index.jsp文件,典型的流程如下:
1,用戶發出 testPage.jsp?query=modrain的請求
2,testPage.jsp上的<wcf:include>根據query參數,匹配/WEB-INF/query/下的modrain.jsp來獲取數據
3,modrain.jsp上的<jp:mondrianQuery id="query01">查詢數據,放入到query01變量中
4,testPage.jsp上的<jp:table id="table01" query="#{query01}"/>根據query01的結果(領域數據) 準備顯示OLAP表格所需的數據(顯示數據)
5,testPage.jsp上的<wcf:render ref="table01" xslUri="/WEB-INF/jpivot/table/mdxtable.xsl"/>根據table01的結果,使用xsl,渲染出OLAP表格。
6,循環第4,5步,使用<jp:navigator>等tag準備navigator,chart的數據然後用<wcf>渲染出圖表和導航系統.
整個流程,第2步的testPage充當Controller調用第3步的Model層,然後第4,5步 執行Martin Flower講的Transform Engine兩步渲染模式----先從領域數據(比如一些java bean)中轉換出格式整齊的,需要顯示的數據(比如一段xml),再用xsl將其渲染爲最終的表現形式。