需求描述

考虑直接在Hive或者Impala等Big Data方案,能够支持MDX查询,现调研一下Mondrian对hive的支持情况。

环境准备

hive环境,采用hive-0.10-cdh4.2.1 客户端程序使用的类库:mondrian-3.6.0、olap4j-1.2.0-SNAPSHOT

数据准备

来源于网上一个数据源,准备四张表 Customer - 客户信息维表 Product - 产品维表 ProductType - 产品类表维表 Sale - 销售记录表 为了方便测试数据与MDX正确性,将数据导入到MySQL中一份,用来与Hive查询结果进行对比。

在MySQL创建对应表及数据

具体SQL语句:

create database hive_test;

use hive_test;

/**用户信息表*/
create table Customer (
cusId int not null,
gender char(1) null,
constraint PK_CUSTOMER primary key(cusId)
); /**产品表*/
create table Product (
proId int not null,
proTypeId int null,
proName varchar(32) null,
constraint PK_PRODUCT primary key(proId)
); /**产品类别表*/
create table ProductType (
proTypeId int not null,
proTypeName varchar(32) null,
constraint PK_PRODUCTTYPE primary key (proTypeId)
); /**销售记录表/
create table Sale (
saleId int not null,
proId int null,
cusId int null,
unitPrice float null,
number int null,
constraint PK_SALE primary key(saleId)
); insert into Customer(cusId,gender) values(1,'F');
insert into Customer(cusId,gender) values(2,'M');
insert into Customer(cusId,gender) values(3,'M');
insert into Customer(cusId,gender) values(4,'F'); insert into ProductType(proTypeId,proTypeName) values(1,'electrical');
insert into ProductType(proTypeId,proTypeName) values(2,'digital');
insert into ProductType(proTypeId,proTypeName) values(3,'furniture'); insert into Product(proId,proTypeId,proName) values(1,1,'washing machine');
insert into Product(proId,proTypeId,proName) values(2,1,'television');
insert into Product(proId,proTypeId,proName) values(3,2,'mp3');
insert into Product(proId,proTypeId,proName) values(4,2,'mp4');
insert into Product(proId,proTypeId,proName) values(5,2,'camera');
insert into Product(proId,proTypeId,proName) values(6,3,'chair');
insert into Product(proId,proTypeId,proName) values(7,3,'desk');
insert into sale(saleId,proId,cusId,unitPrice,number) values(1,1,1,340.34,2);
insert into sale(saleId,proId,cusId,unitPrice,number) values(2,1,2,140.34,1);
insert into sale(saleId,proId,cusId,unitPrice,number) values(3,2,3,240.34,3);
insert into sale(saleId,proId,cusId,unitPrice,number) values(4,3,4,540.34,4);
insert into sale(saleId,proId,cusId,unitPrice,number) values(5,4,1,80.34,5);
insert into sale(saleId,proId,cusId,unitPrice,number) values(6,5,2,90.34,26);
insert into sale(saleId,proId,cusId,unitPrice,number) values(7,6,3,140.34,7);
insert into sale(saleId,proId,cusId,unitPrice,number) values(8,7,4,640.34,28);
insert into sale(saleId,proId,cusId,unitPrice,number) values(9,6,1,140.34,29);
insert into sale(saleId,proId,cusId,unitPrice,number) values(10,7,2,740.34,29);
insert into sale(saleId,proId,cusId,unitPrice,number) values(11,5,3,30.34,28);
insert into sale(saleId,proId,cusId,unitPrice,number) values(12,4,4,1240.34,72);
insert into sale(saleId,proId,cusId,unitPrice,number) values(13,3,1,314.34,27);
insert into sale(saleId,proId,cusId,unitPrice,number) values(14,3,2,45.34,27);

hive中测试数据准备

在虚拟机准备好hive测试环境,采用hive-0.10-cdh4.2.1版本 具体语句:

create database mondrian;
use mondrian;
create table Sale (saleId INT, proId INT, cusId INT, unitPrice FLOAT, number INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY ",";
create table Product (proId INT, proTypeId INT, proName STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ",";
create table ProductType (proTypeId INT, proTypeName STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ",";
create table Customer (cusId INT, gender STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ","; # Customer文件
1,F
2,M
3,M
4,F
load data local inpath "/home/hzwangxx/cdh4/hive/myTmp/Customer" OVERWRITE into table Customer; # ProductType文件
1,electrical
2,digital
3,furniture
load data local inpath "/home/hzwangxx/cdh4/hive/myTmp/ProductType" into table ProductType; # Product数据文件
1,1,washing machine
2,1,television
3,2,mp3
4,2,mp4
5,2,camera
6,3,chair
7,3,desk
load data local inpath "/home/hzwangxx/cdh4/hive/myTmp/Product" into table Product; # Sale数据文件
1,1,1,340.34,2
2,1,2,140.34,1
3,2,3,240.34,3
4,3,4,540.34,4
5,4,1,80.34,5
6,5,2,90.34,26
7,6,3,140.34,7
8,7,4,640.34,28
9,6,1,140.34,29
10,7,2,740.34,29
11,5,3,30.34,28
12,4,4,1240.34,72
13,3,1,314.34,27
14,3,2,45.34,27
load data local inpath "/home/hzwangxx/cdh4/hive/myTmp/Sale" into table Sale;

元数据定义

Cube、Measure等元数据定义见:

<Schema name="hello">
<Cube name="Sales">
<!-- 事实表(fact table) -->
<Table name="Sale"/>
<!-- 客户维 -->
<Dimension name="cusGender" foreignKey="cusId">
<Hierarchy hasAll="true" allMemberName="allGender" primaryKey="cusId">
<Table name="Customer"/>
<Level name="gender" column="gender"/>
</Hierarchy>
</Dimension>
<!-- 产品类别维 -->
<Dimension name="proType" foreignKey="proId">
<Hierarchy hasAll="true" allMemberName="allPro" primaryKey="proId" primaryKeyTable="Product">
<join leftKey="proTypeId" rightKey="proTypeId">
<Table name="Product"/>
<Table name="ProductType"/>
</join>
<Level name="proTypeId" column="proTypeId" nameColumn="proTypeName" uniqueMembers="true" table="ProductType"/>
<Level name="proId" column="proId" nameColumn="proName" uniqueMembers="true" table="Product"/>
</Hierarchy>
</Dimension>
<Measure name="numb" column="number" aggregator="sum" datatype="Numeric"/>
<Measure name="totalSale" aggregator="sum" formatString="$ #,##0.00">
<!-- unitPrice*number所得值的列 -->
<MeasureExpression>
<SQL dialect="generic">unitPrice*number</SQL>
</MeasureExpression>
</Measure>
<CalculatedMember name="averPri" dimension="Measures">
<Formula>[Measures].[totalSale] / [Measures].[numb]</Formula>
<CalculatedMemberProperty name="FORMAT_STRING" value="$ #,##0.00"/>
</CalculatedMember>
</Cube>
</Schema>

测试MDX

1. 查询所有类别产品销售总件数、平均价格和总销售额

"select " + "{[Measures].[numb],[Measures].[averPri],[Measures].[totalSale]} on columns," + "{([proType].[allPro],[cusGender].[allGender])} " + "on rows " + "from [Sales]" 

对Hive支持情况

建立Connection连接方式

建立Connection连接方式有两种:

使用mondrian自带的DriverManager获取Connection实例

mondrian中自带的API

# 这里的Connection、DriverManager、Query、Result等都是mondrian提供的API接口
Connection connection = DriverManager.getConnection(
"Provider=mondrian;" +
"Jdbc=jdbc:hive2://node02:10000/mondrian;" +
"JdbcUser=;JdbcPassword=;" +
"Catalog=/Users/apple/IdeaProjects/hbase-manage/src/main/resources/MiniMart.xml;" +
"JdbcDrivers=org.apache.hive.jdbc.HiveDriver", null); Query query = connection.parseQuery(
"select \n" +
"{[Measures].[numb],[Measures].[averPri],[Measures].[totalSale]} on columns,\n" +
"{([proType].[allPro],[cusGender].[allGender])} \n" +
"on rows\n" +
"from [Sales]\n"); @SuppressWarnings("deprecation")
Result result = connection.execute(query);
PrintWriter pw = new PrintWriter(System.out);
result.print(pw);
pw.flush();

  对应的连接MySQL,只需要将getConnection中的connectString换成如下即可:

Connection connection =  DriverManager.getConnection(
"Provider=mondrian;" +
"Jdbc=jdbc:mysql://localhost:3306/hive_test; JdbcUser=root;" +
"JdbcPassword=123;" +
"Catalog=/Users/apple/IdeaProjects/hbase-manage/src/main/resources/MiniMart.xml;" +
"JdbcDrivers=com.mysql.jdbc.Driver", null);

  测试的时候连接MySQL时,没什么问题,在使用相同的API连Hive的时候,有点问题。down了一下源码发现它的过程是这样的:先去连接池中取一个Connection实例,没有的话通过Factory创建一个Connection放入池里。而在Mondrian创建Factory的时候指定了两个属性:autoCommit和readOnly,RDBMS的Driver都没什么问题,Hive的JDBC提供的HiveConnection中对这两个属性的set方法实现得很诡异,都是直接抛异常了:

  public void setReadOnly(boolean readOnly) throws SQLException {
// TODO Auto-generated method stub
throw new SQLException("Method not supported");
}
public void setAutoCommit(boolean autoCommit) throws SQLException {
if (autoCommit) {
throw new SQLException("enabling autocommit is not supported");
}
}

将这两行抛出异常的地方注释掉,rebuild一下jar包,MDX就可以顺利执行完了。

使用JDK原生的DriverManager获取Connection实例

  可以使用JDK原生的DriverManager获取Connection然后再使用Olap4j的封装成OLapConnection然后再去执行MDX 具体连接示例如下:

 Class.forName("mondrian.olap4j.MondrianOlap4jDriver");
Connection nativeConn = DriverManager.getConnection("jdbc:mondrian:Jdbc=jdbc:hive2://node02:10000/mondrian; JdbcUser=;" +
"JdbcPassword=;" +
"Catalog=/Users/apple/IdeaProjects/hbase-manage/src/main/resources/MiniMart.xml;" +
"JdbcDrivers=org.apache.hive.jdbc.HiveDriver"); OlapConnection olapConn = nativeConn.unwrap(OlapConnection.class); if (olapConn == null) {
throw new IllegalStateException("Connection is null");
}
OlapStatement statement = olapConn.createStatement();
CellSet cellSet = statement.executeOlapQuery("select " +
"{[Measures].[numb],[Measures].[averPri],[Measures].[totalSale]} on columns," +
"{([proType].[allPro],[cusGender].[allGender])} " +
"on rows " +
"from [Sales]") ;
//formatter.
RectangularCellSetFormatter formatter =
new RectangularCellSetFormatter(false); // Print out.
PrintWriter writer = new PrintWriter(System.out);
formatter.format(cellSet, writer);
writer.flush();
statement.close();
olapConn.close();
nativeConn.close();

指定Database

  hive也有类似RDBMS一样有database的概念,在Hive提供的普通Java API中虽然在连接字符串中指定了database,但是它默认的并非你指定的database而是上一次当前客户端或线程使用的database(注:并非default),所以一般使用Hive 客户端必须先执行一下use database。而在OlapConnection和Mondrian提供的Connection都不支持"use database"操作。暂时的解决办法,每次去进行MDX查询的时候先通过普通的Java Api执行一下use database,指定到当前需要查询的数据库中。

Pentaho的Mondrian对Hive的支持的更多相关文章

  1. HIVE 不支持group by 别名

    hive不支持group by 别名,如果需要group by 别名的情况,可以使用 别名的 值作为group by 的值

  2. Hive不支持非相等的join

    由于 hive 与传统关系型数据库面对的业务场景及底层技术架构都有着很大差异,因此,传统数据库领域的一些技能放到 Hive 中可能已不再适用.关于 hive 的优化与原理.应用的文章,前面也陆陆续续的 ...

  3. Hbase对hive的支持没有hdfs的好的原因 及hbase什么时候使用 及rowkey设计技巧

    hive-=mareduce 的  split  在 hbase就是  region了,,,,,,,访问region必须通过hregionserver 会造成regionser负担过大, 另外 reg ...

  4. hive表支持中文设置

    默认创建表时说明中带有中文字段时会显示如下乱码信息: 解决方案: 在hive的元数据库中执行以下SQL语句,然后重新创建刚才的表即可 . ) character set utf8; ) charact ...

  5. hive支持in用法是从0.3.2版本后

    写hive 用in 如分时段,分类型,分平台统计点击量 select substr(createtime,12,2) hour,logtype,os_id,count(*)  from  wizad_ ...

  6. hive支持sql大全(收藏版)

    hive操作数据库还是比较方便的,因此才会有hbase与hive整合.下面我们hive的强大功能吧.为了增强阅读性,下面提几个问题: 1.hive支持哪些运算符? 2.hive是否支持左右连接? 3. ...

  7. Hive ACID和事务表支持详解

    一.ACID介绍 ACID就是常见数据库事务的四大特性:Atomicity(原子性).Consistency(一致性).Isolation(隔离性).Durability(持久性). 在Hive 0. ...

  8. hive中对子查询如in,exists等支持

    案例情况:同事使用公司数据探查跑一段代码,部分代码如下,报错,显示不支持in内的子查询.但是直接用虚拟机去跑的话代码没有任何报错,也出结果,很奇怪. SELECT t1.SIGN_CODE AS bu ...

  9. 基于Ubuntu Hadoop的群集搭建Hive

    Hive是Hadoop生态中的一个重要组成部分,主要用于数据仓库.前面的文章中我们已经搭建好了Hadoop的群集,下面我们在这个群集上再搭建Hive的群集. 1.安装MySQL 1.1安装MySQL ...

随机推荐

  1. [C++]模板类和模板函数

    参考: C++ 中模板使用详解 C++模板详解 概念 为了避免因重载函数定义不全面而带来的调用错误,引入了模板机制 定义 模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模 ...

  2. ceilometer 源码分析(polling)(O版)

    一.简单介绍ceilometer 这里长话短说, ceilometer是用来采集openstack下面各种资源的在某一时刻的资源值,比如云硬盘的大小等.下面是官网现在的架构图 这里除了ceilomet ...

  3. 铁轨(rails, ACM/ICPC CERC 1997,Uva 514)

    铁轨(rails, ACM/ICPC CERC 1997,Uva 514) 题目描述 某城市有一个火车站,铁轨铺设如图所示.有n节车厢从A方向驶入车站,按进站顺序编号为1~n.你的任务是让它们按照某种 ...

  4. 【深度学习的实用层面】(一)训练,验证,测试集(Train/Dev/Test sets)

    在配置训练.验证.和测试数据集的过程中做出正确的决策会更好地创建高效的神经网络,所以需要对这三个名词有一个清晰的认识. 训练集:用来训练模型 验证集:用于调整模型的超参数,验证不同算法,检验哪种算法更 ...

  5. 网页调起App之应用实践

    声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场.举报 新春佳节即将到来,北京的上地&西二旗.望京&国贸.五道口&中关村地区等程序员 ...

  6. Scrum立会报告+燃尽图(Final阶段第三次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2481 项目地址:https://coding.net/u/wuyy694 ...

  7. (第十一周)Beta—review阶段成员贡献分

    项目名:食物链教学工具 组名:奋斗吧兄弟 组长:黄兴 组员:李俞寰.杜桥.栾骄阳.王东涵 个人贡献分=基础分+表现分 基础分=5*5*0.5/5=2.5 成员得分如下: 成员 基础分 表现分 个人贡献 ...

  8. Daily Scrumming 2015.10.23(Day 4)

    今明两天任务表 Member Today’s Task Tomorrow’s Task 江昊 继续学习rails ActiveRecord 数据库迁移 域名备案申请 学习rails router配置与 ...

  9. Teamwork(The sixth day of the team)

    每日列会过后,我们的工作进度都有所进展了,好开心,但是还不是我们想要的,我们想做得更快,更好.

  10. 先做一个用来测试的chrome浏览器插件

    如何制作chrome插件 在项目汇报中,有同学提到了想要了解如何制作插件,特写该篇博客供大家查阅~ 一个简单的插件需要manifest.json.popup.html.popup.js.content ...