hengheng123456789

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            297 Posts :: 68 Stories :: 144 Comments :: 0 Trackbacks

          一、引言

          Mondrian, 蒙得里安?皮特 1872-1944 荷蘭畫家,作品以交錯的三原色為基色的垂直線條和平面為特點,他的著作包括 新造型主義 (1920 年),對抽象藝術(shù)的發(fā)展曾經(jīng)產(chǎn)生很深影響。金山詞霸如是說。

          不過 , 本文所要討論的可不是這位藝術(shù)家。那到底 mondrian 是什么呢?

          Mondrian 是一個開源項目。一個用Java寫成的OLAP(在線分析性處理)引擎。它用MDX語言實現(xiàn)查詢,從關(guān)系數(shù)據(jù)庫(RDBMS)中讀取數(shù)據(jù)。然后經(jīng)過Java API用多維的方式對結(jié)果進(jìn)行展示。

          我們都知道,在線分析處理(OLAP)要實時地分析大量數(shù)據(jù)。“online”這個詞的含義就是即使相關(guān)的數(shù)據(jù)量是巨大的可能以GB為單位系統(tǒng)也要足夠快的響應(yīng)以顯示結(jié)果。

          OLAP 用了多維分析的技術(shù)。盡管關(guān)系型數(shù)據(jù)庫所存儲的所有數(shù)據(jù)都是以行和列的形式存在的,但一個多維數(shù)據(jù)集還是可以由軸(axes)和單元(cell)組成。

          ?

          在上面的例子中,時間是個維度( dimension ),而它下面的層次( Hierarchies )又分為半年、季度等級別(Level)

          二、感性認(rèn)識,運行一個小實例

          我們暫時先不討論Mondrian所用到的一些技術(shù)。我們可以先從一個小例子開始,不必在意每個細(xì)節(jié),只是希望大家有個感性認(rèn)識先。在實施這個例子的過程中,或許讀者就能見些端倪。

          首先應(yīng)該到http://sourceforge.net/projects/mondrian/下載mondrian的最新版本。這是一個zip包,包括我們要用到的lib和一個例子。

          當(dāng)然,讀者完全可以運行mondrian自帶的實例,不過這個例子有些紛繁復(fù)雜,除了Mondrian本身還有其它技術(shù)在里面,不大容易講清楚,也不太適合初學(xué)者學(xué)習(xí)。所以,筆者在這里設(shè)計一個簡潔干凈的最小化實例。

          本文所闡述的實例環(huán)境是Windows2000+Tomcat+Oracle。并且認(rèn)為讀者已經(jīng)針對jdkTomcat做了正確的開發(fā)環(huán)境的設(shè)置。

          2 1 準(zhǔn)備工作

          %Tomcat%/webapp依次建立mywebappmywebapp/WEB-INFmywebapp/WEB-INF/lib, mondrian.jar,javacup.jar, x alan.jar,junit.jar 等相關(guān)的jarcopy % TOMCAT_HOME%/ webapps/mywebapp/lib 下。

          2 2 數(shù)據(jù)庫結(jié)構(gòu)

          在這個tiny的系統(tǒng)中,數(shù)據(jù)庫有3個表tb_employee(職員表),tb_time(時間表),tb_salary(薪酬表)。表結(jié)構(gòu)如下:

          drop table tb_employee;

          create table tb_employee

          (

          ???? employee_id???? number,???????????? -- 職員id????

          ???? employee_name?? varchar2(10)??????? -- 職員姓名

          );

          ?

          drop table tb_time;

          create table tb_time

          (

          ??? time_id?? number,??????? -- 時間id

          ??? the_year? char(4),?????? --

          ??? the_month char(2)??????? --

          );

          ?

          drop table tb_salary;

          create? table tb_salary

          (

          ??? employee_id? number,??????????????? -- 職員id???

          ??? time_id????? number,??????????????? -- 時間id

          ??? salary?????? number(19,4)?????????? -- 薪酬

          );

          ?

          當(dāng)然,為了使系統(tǒng)能夠運行,還需要讀者向數(shù)據(jù)庫表中插入一些數(shù)據(jù)。

          2 3 根據(jù)數(shù)據(jù)庫表的結(jié)構(gòu),書寫 schema 文件

          <?xml version="1.0"?>

          <Schema name="Mondrian">

          <Cube name="CubeTest">

          ??? <Table name="TB_SALARY" />

          ???

          ??? <Dimension name="Employee"? foreignKey="EMPLOYEE_ID" >

          ??????? <Hierarchy hasAll="true" primaryKey="EMPLOYEE_ID">? ???????

          ??????????? <Table name="TB_EMPLOYEE" />

          ??????? <Level name="employeeId" column="EMPLOYEE_ID"?? uniqueMembers="true" >

          ??????????????? <Property name="employeeName" column="EMPLOYEE_NAME"/>

          ??????????? </Level>

          ??????? </Hierarchy>

          ??? </Dimension>

          ??? <Dimension name="Time" foreignKey="TIME_ID" >

          ??? ??? <Hierarchy? hasAll="false" primaryKey="TIME_ID" >

          ??????????? <Table name="TB_TIME" />

          ??????????? <Level name="year" column="THE_YEAR" uniqueMembers="false" />

          ??????????? <Level name="month" column="THE_MONTH" uniqueMembers="false" />

          ??????? </Hierarchy>

          ??? </Dimension>???????

          ???

          ??? <Measure name="Salary" column="SALARY" aggregator="sum" />

          ??? </Cube>

          </Schema>

          ?

          文件路徑為mywebapp/WEB-INF/mondriantest.xml

          2 4 利用 MDX 查詢

          mywebapp/mondriantest.jsp

          1 <%@ page import="mondrian.olap.*"%>

          <%

          2 Connection connection =

          ? DriverManager.getConnection

          ("Provider=mondrian;????????????????

          ?Jdbc=jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:dbname;

          JdbcUser=dbuser;????????????????????????????????????

          ?JdbcPassword=dbpasswd;???????????????????????????????

          Catalog=file:///c:/Tomcat4.1/webapps/mywebapp/WEB-INF/mondriantest.xml;

          JdbcDrivers=oracle.jdbc.driver.OracleDriver;",null,false);????

          3 String queryStr=

          "select {[Measures].[Salary]} ON COLUMNS,

          {[Employee].[employeeId].Members} ON ROWS

          from CubeTest ";

          ?

          4 Query query =connection.parseQuery(queryStr);

          5 Result result = connection.execute(query);

          out.println("get result");

          %>

          2 5 運行

          這時啟動to mcat, 在瀏覽器地址欄中輸入

          http://localhost:8080/mywebapp/ mondriantest .jsp 即可。

          三、深入探討

          3 1 API

          mondrian 為客戶端應(yīng)用程序提供了API接口以進(jìn)行查詢。?而這些API對于任何用過JDBC的人都會覺得似曾相識的。主要的不同點是查詢語言的不同:Mondrian用的是MDX ('Multi-Dimensional eXpressions'), JDBC 則用的是 SQL

          JDBC 一樣,也是要經(jīng)過建立連接,形成查詢語句,執(zhí)行查詢得到結(jié)果集等幾個步驟的。

          我們來看看 mondriantest.jsp 的代碼

          1行:import mondrian.olap.*

          這是引入我們所需的類,下面要用到的DriverManagerConnectionQueryResult都在這個package內(nèi)。這個package一般位于mondrian.jar中。

          2行:Connection connection =

          ? DriverManager.getConnection

          ("Provider=mondrian;????????????????

          ?Jdbc=jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:dbname;

          JdbcUser=dbuser;????????????????????????????????????

          ?JdbcPassword=dbpasswd;???????????????????????????????

          Catalog=file:///c:/Tomcat4.1/webapps/mywebapp/WEB-INF/mondriantest.xml;

          JdbcDrivers=oracle.jdbc.driver.OracleDriver;",null,false);?

          通過DriverManager創(chuàng)建一個Connection的實例,建立起數(shù)據(jù)庫連接。

          其中Jdbc=jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:dbname; 是設(shè)置數(shù)據(jù)庫的ip和庫名。JdbcUser=dbuser;? 設(shè)置數(shù)據(jù)庫用戶。JdbcPassword=dbpasswd;?? 設(shè)置用戶密碼。而

          Catalog=file:///c:/Tomcat4.1/webapps/mywebapp/WEB-INF/mondriantest.xml; 就是設(shè)置MDX語句查詢要對應(yīng)的schema文件的路徑

          3行:String queryStr=

          "select {[Measures].[Salary]} ON COLUMNS,

          {[Employee].[employeeId].Members} ON ROWS

          from CubeTest ";

          形成MDX的查詢語句。MDX語句的形式和schema文件的設(shè)定是密切相關(guān)的,當(dāng)然schema文件的形成也是由數(shù)據(jù)庫結(jié)構(gòu)決定的。

          4行:Query query =connection.parseQuery(queryStr);MDX語句進(jìn)行分析處理,是否符合schema文件定義、數(shù)據(jù)庫結(jié)構(gòu)和數(shù)據(jù)庫數(shù)據(jù)。

          5行:Result result = connection.execute(query);執(zhí)行查詢,得到結(jié)果集。

          我們發(fā)現(xiàn)Query類似于JDBCStatement,Result則酷似于ResultSet

          3 2 schema

          3 2 1 什么是 schema

          schema 定義了一個多維數(shù)據(jù)庫。包含了一個邏輯模型,而這個邏輯模型的目的是為了書寫 MDX 語言的查詢語句。這個邏輯模型實際上提供了這幾個概念: Cubes, 維度( Dimensions ), 層次( Hierarchies ),級別( Levels ),和成員( Members )。

          schema 文件就是編輯這個 schema 的一個 xml 文件。在這個文件中形成邏輯模型和數(shù)據(jù)庫物理模型的對應(yīng)。

          3 2 2 schema 的邏輯結(jié)構(gòu)

          3 2 2 1 Cube

          一個 Cube 是一系列維度 (Dimension) 和度量 (Measure) 的集合區(qū)域。在 Cube 中, Dimension Measure 的共同地方就是共用一個事實表。

          例:

          <Cube name="CubeTest">

          ??? <Table name="TB_SALARY" />

          ?? …….

          </Cube>

          <Table> 標(biāo)簽確定了所用的事實表的表名。

          3 2 2 2 Measure

          一個度量,簡單的說,就是要被計算的值。

          例:

          <Measure name="Salary" column="SALARY" aggregator="sum" />

          <Measure> 標(biāo)簽有 3 個必要的屬性 name (度量名), column (在事實表中的字段名) , aggregation (聚合所用的方法)。

          3 2 2 3 Dimenesion

          而維度一般有其相對應(yīng)的維度表。

          例:

          <Dimension name="Time" foreignKey="TIME_ID" >

          ??????? <Hierarchy? hasAll="false" primaryKey="TIME_ID" >

          ??????????? <Table name="TB_TIME" />

          ??????????? <Level name="year" column="THE_YEAR" uniqueMembers="false" />

          ??????????? <Level name="month" column="THE_MONTH" uniqueMembers="false" />

          ??????? </Hierarchy>

          </Dimension>

          一般Dimesion包含層次(Hierarchy),而hierarchy是由級別(Level)組成。

          <Dimension> 標(biāo)簽的foreignKey是事實表中的字段,<Hierarchy>標(biāo)簽的primaryKey是維度表中的字段,通過這種方式把事實表和維度表關(guān)聯(lián)起來。<Hierarchy>標(biāo)簽下的<Table>標(biāo)簽就指明了維度表名。而若干個Level對應(yīng)著維度表的若干字段。

          3 3 MDX 語言

          MDX 是為了查詢多維數(shù)據(jù)的,而SQL是為了查詢關(guān)系數(shù)據(jù)庫的。而Mondrian所涉及到的一些MDX概念、MDX語法以及系統(tǒng)定義的MDX函數(shù)和微軟的MDX十分接近,差別微小。完全可以參考微軟的幫助文檔進(jìn)行學(xué)習(xí)。在此就不在贅述。

          四、結(jié)語

          Mondrian 作為基于javaOLAP引擎,而且是開源的項目,為那些基于java的項目而要脫離微軟構(gòu)架但又不得不對大量數(shù)據(jù)進(jìn)行分析的項目又提供了一種可行的方案。希望它也能象 蒙得里安?皮特對抽象藝術(shù)的發(fā)展產(chǎn)生影響一樣起到一定的作用。

          posted on 2006-12-01 16:55 哼哼 閱讀(2213) 評論(3)  編輯  收藏 所屬分類: BI

          Feedback

          # re: Pentaho之mondrian“藝術(shù)家” 2008-01-10 09:57 wdmcln@dsy
          你的msn是多少,想和你交流一下?
          我做的mondrian例子,不能輸出結(jié)果集,沒有達(dá)到網(wǎng)上說的那種效果!
          在單步測試的時候,已經(jīng)看維度里面有值,找了好久,也沒找到怎么輸出結(jié)果集的方法
          PrintWriter pw = new PrintWriter(System.out);
          result.print(pw);
          這樣沒有任何輸出,希望到得到作者的幫助!
          我的msn:wdmcln@hotmail.com  回復(fù)  更多評論
            

          # re: Pentaho之mondrian“藝術(shù)家” 2009-02-16 09:56 pentaho
          pentaho中文社區(qū)挺不錯的,里面有很多pentaho和其它商業(yè)智能產(chǎn)品的資料,推薦去看看,地址是www.pentahoclub.cn  回復(fù)  更多評論
            

          # re: Pentaho之mondrian“藝術(shù)家” 2011-07-28 17:18 alishan212
          Pentaho QQ 群, Pentaho China

          Weclome to join in Pentaho Projects in China, we would like to share any experience with you and get cooperations each other.

          Pentaho 項目群成立了,歡迎有識之士加入,共同討論分享 Pentaho 經(jīng)驗和 項目合作。

          Pentaho 項目 QQ群: 164774111
            回復(fù)  更多評論
            

          主站蜘蛛池模板: 岳阳市| 司法| 湘阴县| 香格里拉县| 邳州市| 泸水县| 湘西| 临漳县| 尼玛县| 廉江市| 桐梓县| 内江市| 锦屏县| 定陶县| 剑阁县| 聂拉木县| 石泉县| 平乐县| 祁门县| 霍州市| 云浮市| 辽源市| 江津市| 大丰市| 色达县| 阜新市| 呼伦贝尔市| 荔浦县| 八宿县| 巨鹿县| 齐河县| 翁源县| 昌宁县| 琼中| 砀山县| 长子县| 高淳县| 永昌县| 永福县| 尚志市| 灌云县|