需求描述

考虑直接在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. 算法设计:UNION-FIND算法实现

    在上周的算法设计课程中,我们学习了UNION-FIND算法,该算法用来对不相交集进行查询与合并操作,但任何优秀的算法都必须要用实际的代码来进行实现,接下来我们就来看看具体的代码实现 1. 不相关集数据 ...

  2. 【SIKIA计划】_05_Unity5.3开发2D游戏笔记

    一.界面基本操作 01.Project基本分类[Audios]音效[Material]材质[Prefabs]预制[Scenes]场景[Scripts]脚本[Sprites]精灵 02.Project丶 ...

  3. 最优方向法(MOD)

    算法描述 求解模型: \[\min\sum\limits_i\|x_i\|_0 \quad \mathrm{s.t.} \; \|Y-DX\|^2_F \leq \varepsilon\] 或 \[\ ...

  4. arp与rarp

  5. Python遗传算法工具箱DEAP框架分析

    本文主要介绍python遗传算法工具箱DEAP的实现.先介绍deap的如何使用,再深入介绍deap的框架实现,以及遗传算法的各种实现算法. 代码可以参考 https://github.com/suma ...

  6. 可道云kodexplorer搭建私有云后的配置优化

    一.上传下载速度优化首先明确可道云没有对上传下载做任何限制,速度快慢和网络环境有关.可道云是基于http上传,所以和其他http上传速度基本一致:可以对比其他web系统或网站说附件上传速度.同其他例如 ...

  7. Hyperledger Fabric MSP Identity Validity Rules——MSP身份验证规则

    MSP Identity Validity Rules——MSP身份验证规则 正如Hyperledger Fabric Membership Service Providers (MSP)——成员服务 ...

  8. kali linux执行apt-get update失败(数字签名过期)

    想要安装某个软件,执行apt-get update 失败,出现下面的错误: 自己查看了更新源是没有问题的,根据提示的错误google了一下,发现是数字签名过期了. 执行下面命令: apt-key ad ...

  9. webpack入门指南-step04

    一.建立项目 建一个文件夹,然后新建一个package.json的文件在项目根目录下 如果你使用git管理你的这个项目的话,建议你新建一个.gitignore文件,不要让git提交一些node依赖的模 ...

  10. Daily Scrum (2015/10/22)

    今天我们发现了源代码并不能直接在PC上运行.通过学长我们了解到我们需要在服务器上链接上数据库才能正常运行,所以找了老师要了地址后进入了正常工作.由此我们的PM增添了一些新的任务,团队的总工作时间有所增 ...