|
|
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已! |
|
恭喜您是本站第 1671628
位訪客!
登入 | 註冊
|
|
|
|
發表者 |
討論內容 |
冷日 (冷日) |
發表時間:2008/3/19 5:51 |
- Webmaster
- 註冊日: 2008/2/19
- 來自:
- 發表數: 15771
|
- [分享]mondrian,OLAP引擎
- 一、引言
Mondrian, 蒙得里安·皮特1872-1944荷兰画家,作品以交错的三原色为基色的垂直线条和平面为特点,他的著作包括 新造型主义(1920年),对抽象艺术的发展曾经产生很深影响。——金山词霸如是说。
不过,本文所要讨论的可不是这位艺术家。那到底mondrian是什么呢?
Mondrian是一个开源项目。一个用Java写成的OLAP(在线分析性处理)引擎。它用MDX语言实现查询,从关系数据库(RDBMS)中读取数据。然后经过Java API用多维的方式对结果进行展示。
我们都知道,在线分析处理(OLAP)要实时地分析大量数据。“online”这个词的含义就是即使相关的数据量是巨大的——可能以GB为单位——系统也要足够快的响应以显示结果。
OLAP用了多维分析的技术。尽管关系型数据库所存储的所有数据都是以行和列的形式存在的,但一个多维数据集还是可以由轴(axes)和单元(cell)组成。
在上面的例子中,时间是个维度(dimension),而它下面的层次(Hierarchies)又分为半年、季度等级别(Level)。
二、感性认识——运行一个小实例
我们暂时先不讨论Mondrian所用到的一些技术。我们可以先从一个小例子开始,不必在意每个细节,只是希望大家有个感性认识先。在实施这个例子的过程中,或许读者就能见些端倪。
首先应该到http://sourceforge.net/projects/mondrian/下载mondrian的最新版本。这是一个zip包,包括我们要用到的lib和一个例子。
当然,读者完全可以运行mondrian自带的实例,不过这个例子有些纷繁复杂,除了Mondrian本身还有其它技术在里面,不大容易讲清楚,也不太适合初学者学习。所以,笔者在这里设计一个简洁干净的最小化实例。
本文所阐述的实例环境是Windows2000+Tomcat+Oracle。并且认为读者已经针对jdk和Tomcat做了正确的开发环境的设置。
2.1准备工作
在%Tomcat%\webapp\依次建立mywebapp,mywebapp\WEB-INF,mywebapp\WEB-INF\lib,把
mondrian.war\WEB-INF\lib\mondrian.jar,javacup.jar, xalan.jar,junit.jar等相关的jar包copy到%TOMCAT_HOME%\webapps\mywebapp\lib\下。
2.2数据库结构
在这个tiny的系统中,数据库有3个表tb_employee(职员表),tb_time(时间表),tb_salary(薪酬表)。表结构如下:
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) --薪酬
);
当然,为了使系统能够运行,还需要读者向数据库表中插入一些数据。
2.3根据数据库表的结构,书写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运行
这时启动tomcat,在浏览器地址栏中输入
http://localhost:8080/mywebapp/ mondriantest.jsp即可。
三、深入探讨
3.1 API
mondrian为客户端应用程序提供了API接口以进行查询。 而这些API对于任何用过JDBC的人都会觉得似曾相识的。主要的不同点是查询语言的不同:Mondrian用的是MDX('Multi-Dimensional eXpressions'),而JDBC则用的是SQL。
和JDBC一样,也是要经过建立连接,形成查询语句,执行查询得到结果集等几个步骤的。
我们来看看mondriantest.jsp的代码
第1行:import mondrian.olap.*
这是引入我们所需的类,下面要用到的DriverManager、Connection、Query、Result都在这个package内。这个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创建一个Connection的实例,建立起数据库连接。
其中Jdbc=jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:dbname; 是设置数据库的ip和库名。JdbcUser=dbuser; 设置数据库用户。JdbcPassword=dbpasswd; 设置用户密码。而
Catalog=file:///c:/Tomcat4.1/webapps/mywebapp/WEB-INF/mondriantest.xml; 就是设置MDX语句查询要对应的schema文件的路径
第3行:String queryStr=
"select {[Measures].[Salary]} ON COLUMNS,
{[Employee].[employeeId].Members} ON ROWS
from CubeTest ";
形成MDX的查询语句。MDX语句的形式和schema文件的设定是密切相关的,当然schema文件的形成也是由数据库结构决定的。
第4行:Query query =connection.parseQuery(queryStr);对MDX语句进行分析处理,是否符合schema文件定义、数据库结构和数据库数据。
第5行:Result result = connection.execute(query);执行查询,得到结果集。
我们发现Query类似于JDBC的Statement,而Result则酷似于ResultSet。
---未完,待續---
|
|
|
冷日 (冷日) |
發表時間:2008/3/19 5:55 |
- Webmaster
- 註冊日: 2008/2/19
- 來自:
- 發表數: 15771
|
- [分享]穷人的通用OLAP方案I
- 穷人的通用OLAP方案I- -
缘起 从前到现在,用户需要从IT系统中获取信息的变化无常与程序员从传统数据库中制作报表的代价是一个永恒的矛盾。 这边厢程序员为了应付客户忽然而至的报表需求痛苦不已, 客户只想要他想知道的东西,不会管查询语句有多么复杂,优化从海量数据中提取报表的速度有多么困难。
那边厢客户为了等程序员做一个报表,快则半天,慢则一周,事情都过去了。明明只想知道一样很简单的东西, 程序员却要抱怨查询是多么复杂,数据结构是如何制约。有时候出一个报表要呆在屏幕前等半天。
而OLAP是唯一一种真正让用户获得自己所需要的报表而且不用付出巨大实现代价的方法。它能够让用户自由的定制自己的查询条件,观察、累计的维度,最后从海量数据中快速生成它。
方案 经过几年的发展,各大数据库供应商都有了自己的OLAP方案。不过我们一来不想把产品绑定在某个数据库上,二来没钱,所以还是要寻求穷人们自己的免费且底层数据库通用的方案。 从AgileJava的Blog上,看到了Mondrian + JPivot:
<A HREF="http://sourceforge.net/projects/mondrian">Mondrian</A> 蒙德里安,OLAP核心引擎,负责从关系数据库中计算、缓存数据,响应来自表现层的使用MS家 MDX语法的查询。这个微软家的MDX语法,学起来并不难,SQL Server的书也统统有教。 在这一层要做的事情就是定义一个schema元模型,包括 维度(Dimensions), 层次(Hierarchies),级别(Levels),和成员(Members)等。Mondrian要根据它来从关系数据库中聚合数据响应MDX语法的查询。
<A HREF="http://jpivot.sourceforge.net/">JPivot</A> OLAP JSP custom tag library。提供OLAP Navigator与多 维数据的显示,并支持图表生成和Export to Excel。Mondrian的御用表现层。
初遇 Mondrian用了MS家著名的FoodMart数据作例子,Access作底层数据库,JPivot做表现层,让你几分钟之内就能把Example跑起来,感受一下OLAP报表是什么样子的。跑完一遍之后,我就发现做个客户自定制的OLAP报表如此简单.....
|
|
|
冷日 (冷日) |
發表時間:2008/3/19 5:56 |
- Webmaster
- 註冊日: 2008/2/19
- 來自:
- 發表數: 15771
|
- [分享]穷人的通用OLAP方案II
- 如前所说,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的列名必须全大写。
|
|
冷日 (冷日) |
發表時間:2008/3/19 5:57 |
- Webmaster
- 註冊日: 2008/2/19
- 來自:
- 發表數: 15771
|
- [分享]窮人的通用OLAP方案III--JPivot表現層
- 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將其渲染為最終的表現形式。
|
|
|