hive之40分钟搞定数据仓库hive及java操作hive
1 hive简介
1.1 什么是Hive?
Hive是基于Hadoop HDFS之上的数据仓库。
我们可以把数据存储在这个基于数据的仓库之中,进行分析和处理,完成我们的业务逻辑。
本质上就是一个数据库
它可以来保存我们的数据,Hive的数据仓库与传统意义上的数据仓库还有区别。
一般来说,我们也可以基于传统方式(Oracle或者MySQL数据库)来搭建这个数据仓库,这个时候数据仓库中的数据是保存在Oracle或者MySQL的数据库当中的。
Hive跟传统方式是不一样的,Hive是建立在Hadoop HDFS基础之上的数据仓库基础框架。也就是说
--Hive这个数据仓库中的数据是保存在HDFS上。
--Hive可以用ETL的方式来进行数据提取转化加载。
--Hive定义了简单的类似SQL查询语言,称为HQL。
--Hive允许熟悉MapReduce开发者的开发自定义的mapper和reducer来处理內建的mapper和reducer无法完成的复杂的分析工作。
--Hive是SQL解析引擎,它将SQL语句转移成M/R Job,然后在Hadoop上执行。把执行的结果最终反映给用户。
--Hive的表其实就是HDFS的目录,Hive的数据其实就是HDFS的文件
1.2 什么是数据仓库?
实际上就是一个数据库。我们可以利用数据仓库来保存我们的数据。
与一般意义上的数据库不同。数据仓库是一个面向主题的、集成的、不可更新的、随时间不变化的数据集合,它用于支持企业和组织的决策分析处理。
1)面向主题的:
数据仓库中的数据是按照一定的主题来组织的。*主题:指的是用户使用数据仓库进行决策时所关心的重点方面。
2)集成的:
数据仓库中的数据来自于分散的操作性的数据,我们把分散性的数据的操作性的数据从原来的数据中抽取出来进行加工和处理,然后满足一定的要求才可以进入我们的数据仓库。
原来的数据,可能来源于我们的Oracle、MySQL等关系型数据库,文本文件,或者其他的系统。将不同的数据集成起来就形成了数据仓库。
3)不可更新的
也就是说数据仓库主要是为了决策分析所提供数据,所以涉及的操作主要是数据的查询。我们一般都不会再数据仓库中进行更新和删除。
4)随时间不变化
数据仓库中的数据是不会随时间产生变化的集合。
1.3 数据仓库的结构和建立过程
1)数据源:
有可能来自由业务数据系统(关系型数据库),文档资料(csv,txt等),其他数据
2)数据存储和管理:
俗称的ETL的过程。
抽取(Extract):把数据源的数据按照一定的方式读取出来
转换(Transform):不同数据源的数据它的格式是不一样的,不一定满足我们的要求,所以需要按照一定的规则进行转换。
装载(Load):将满足格式的数据存取到数据仓库之中。
3)数据仓库引擎:
建立了数据仓库以后,当然是提供对外的数据服务,所以产生了数据仓库引擎。
在数据仓库引擎之中包含有不同的服务器,不同的服务器提供不同的服务。
4)前端展示:
前端展示的数据均来自数据仓库引擎中的各个服务。而服务又读物数据仓库中的数据。
数据查询
数据报表
数据分析
各类应用
1.4 OLTP应用与OLAP应用
数据处理大致可以分成两大类
联机事务处理OLTP(on-line transaction processing):主要面向事务。
联机分析处理OLAP(on-line analytical processing):主要面向查询。
OLTP是传统的关系型数据库的主要应用。主要是基本的、气场的事务处理,例如银行交易。
OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。
OLTP系统强调数据库内存效率,强调内存各种指标的命令率,强调绑定变量,强调并发操作。
OLAP系统泽强调数据分析,强调SQL执行市场,强调磁盘I/O,强调分区等。
1.5 Hive的体系结构之元数据
Hive将元数据(meta data)存储在数据库中(meta store),支持mysql,oracle,derby(默认)等数据库。
Hive中的元数据包括表的名字,表的列和分区以及属性,表的属性(是否为外部表等),表的数据所在目录等。
1.6 Hive的体系结构之HQL的执行过程
一条HQL语句如何在Hive的数据仓库当中中进行查询的?
由解释器、编译器、优化器来共同完成HQL查询语句从词法解析、语法解析、编译、优化以及查询计划(Plan)的生成。
生成的查询计划存储在HDFS中,并在随后又MapReduce调用执行。
1.7 Hive的表
1)表
--Table:内部表
--Partition:分区表
--External Table:外部表
--Bucket Table:桶表
2)视图
是一个逻辑概念,类似于我们的表
3)内部表
--与数据库中的Table在概念上是类似的。
--每一个Table在Hive中都有一个相应的存储数据。
--所有的Table数据(不包括External Table)都保存在这个目录中。
--删除表的时候,元数据与数据都会被删除。
创建表的命令:
create table t1 (tid int, tname string, age int;)
创建表的同事插入数据:
create table t4 as select * from sample_data;
变更表结构:如添加列
alter table t1 add columns (qnglish int);
删除表:会将表移入到回收站当中。
drop table t1;
4)分区表(Partition Table)
--Partition对应于数据库中的Partition列的密集索引
--在Hive中,表中的一个Partition对应于表下的一个目录,所有的Partition的数据都存储在对应的目录中。
创建一张基于性别的分区表,以逗号分隔:
create table partition_table(sid int, sname string) partitioned by (gender string)
row format delimited fields terminated by ',';
创建之后,查询一下表的结构可以看分区信息。
向分区表中插入数据
insert into table partition_table partition(gender='M') select sid, sname from student where gender='M';
分区表是非常有用的,当我们的数据量非常大的时候,我们需要按照一定的条件将数据分区,
这样在我们查询操作的时候就能降低需要遍历的记录数,从而提高查询的效率。
5)外部表(External Table)
--指向已经在HDFS中存在的数据的表,它也可以来创建Partiton
--它和内部表在元数据的组织上是相同的,也就是说外部表依然是保存在我们的数据库当中。而实际数据的存储则有较大的差异。
--外部表"只是一个过程",已经为大家精心准备了大数据的系统学习资料,从Linux-Hadoop-spark-......,需要的小伙伴可以点击加载数据和创建表同事完成,并不会移动到数据仓库目录中,只是与外部数据建立一个链接。当删除一个外部表时,仅仅删除该链接。
创建外部表
create external table external_student(sid int, sname string, age int) location '/tmp/chenjian/';
*location是HDFS中的路径。
6)桶表(Bucket Table)
--桶表是对数据进行哈希取值,然后放到不同文件中存储。相当于oracle中的散列分区表。
桶表中的数据是经过哈希运算之后,将之打散了存在文件当中。这样的好处是可以避免造成"热块"。
创建桶表
create table bucket_table(sid int, sname string, age int) clustered by (sname) into 5 buckets
7)视图(View)
--视图是一种虚表,是一个逻辑概念;可以扩越多张表。
--视图建立在已有表的基础上,视图赖以建立的这些表称为基表。
--视图可以简化复杂的查询。(最大的优点)
创建视图
create view view_emp as <SQL语句>
1.8 测试Hive
1) 创建数据库
create database userdb;
use userdb;
2) 创建表emp
CREATE TABLE IF NOT EXISTS emp ( eid int, name String,
salary String, destination String)
COMMENT 'Employee details'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ' '
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
文件
1201 Gopal 45000 Technicalmanager
1202 Manisha 45000 Proofreader
1203 Masthanvali 40000 Technicalwriter
1204 Kiran 40000 HrAdmin
1205 Kranthi 30000 OpAdmin
3) 导入数据到hive数据仓库
LOAD DATA LOCAL INPATH '/home/hdfs/emp.txt' OVERWRITE INTO TABLE emp;
4) 插入数据,
insert into emp values(1333,4321,432,4321);
5) hive默认不支持数据的update和delete,要想支持行级insert、update、delete,需要配置Hive支持事务。
1.9 java连接hive
创建maven工程,pom配置如下:
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>
关键代码:
//通用查询方法
public List<Map<String ,Object>> executeQuery(String sql,Object[] params) {
conn=getConnection();//获取连接
List<Map<String ,Object>> objList= new ArrayList<Map<String ,Object>>();//接收所有数据
try {
ps=conn.prepareStatement(sql);
ps=setParam(ps, params);
rs=ps.executeQuery();//执行查询,并返回结果集
ResultSetMetaData rsmd=rs.getMetaData();//获取所有的列数
while(rs.next()){//循环遍历结果集
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 0; i < rsmd.getColumnCount(); i++) {
//获取列名并转小写
map.put(rsmd.getColumnName(i+1).toLowerCase(), rs.getObject(i+1));
}
objList.add(map);//封装每一行数据
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
closeConnection(conn, ps, rs);
}
return objList;
}
/**
* @param args
*/
public static void main(String[] args) {
HiveDao bd = new HiveDao();
List<Map<String, Object>> executeQuery = bd.executeQuery("select * from emp", null);
for (Map<String, Object> map : executeQuery) {
System.out.println(map);
}
}
}