需求描述

考虑直接在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. Vue2.0原理-模板解析

    下面这段代码,vue内部做了什么操作?我去源码里面找找看 new Vue({ el: '#app' }) 入口 vue 的入口文件在 src/core/instance/index.js, 里面一进来 ...

  2. python容器类型的协议

    1.协议(Protocols)与其他编程语言中的接口恒相似,它规定你哪些地方必须要定义,然而在python中的协议就显得不那么正式,事实上,在python中,协议更像是一种指南. 2.序列类型和映射类 ...

  3. 获取本地ip和获取公网ip

    import socket def get_local_ip(): ''' 获取本地ip地址 :return: ''' s = socket.socket(socket.AF_INET, socket ...

  4. CHAPTER 40 Science in Our Digital Age 第40章 我们数字时代的科学

    CHAPTER 40 Science in Our Digital Age 第40章 我们数字时代的科学 The next time you switch on your computer, you ...

  5. GlusterFS分布式存储集群-2. 使用

    参考文档: Quick Start Guide:http://gluster.readthedocs.io/en/latest/Quick-Start-Guide/Quickstart/ Instal ...

  6. NO.2:自学tensorflow之路------BP神经网络编程

    引言 在上一篇博客中,介绍了各种Python的第三方库的安装,本周将要使用Tensorflow完成第一个神经网络,BP神经网络的编写.由于之前已经介绍过了BP神经网络的内部结构,本文将直接介绍Tens ...

  7. kerkee demo编译连接过程中遇到的问题及解决方法(iOS)

    https://github.com/kercer/kerkee_ios 1.刚打开这个demo的时候是下图这个样子的,我们很自然的可以想到将kerkee.xcoderproj添加到项目里面 2.将k ...

  8. 第35次Scrum会议(11/23)【欢迎来怼】

    一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文小组照片 二.开会信息 时间:2017/11/23 17:03~17:24,总计21min.地点:东北师 ...

  9. 爱码室Crawler & classification module项目工作分配

    项目情况 爬虫项目是上届学生遗留下来的项目,他们已经实现了基础的功能,而我们来负责完善,主要需要解决的问题是怎么让爬虫脱离爬和停的繁琐指令,更加的智能化.所以我们的计划是在前人的源码基础上,加以修改测 ...

  10. 20162314 《Program Design & Data Structures》Learning Summary Of The Second Week

    20162314 2017-2018-1 <Program Design & Data Structures>Learning Summary Of The Second Week ...