数据分析引擎:Hive

大数据的终极目标:使用SQL语句来处理大数据
1、Hadoop的体系架构中:
)Hive:支持SQL
)Pig: 支持PigLatin
2、Spark的体系架构中:
(*)Spark SQL:类似Hive
支持SQL、支持DSL

3、另一个:Impala

一、什么是Hive?
1、Hive是基于HDFS之上的一个数据仓库
Hive HDFS
表 目录
数据 文件
分区 目录
桶 文件

2、Hive基于Hadoop之上的一个数据分析引擎
   Hive是一个翻译器
	Hive 2.x 以前:SQL -----> Hive  ----> MapReduce
	Hive 2.x 以后:推荐使用Spark作为SQL的执行引擎(只针对Hadoop 3.x以前)
	               推荐《Hive on Spark文档》

3、Hive支持SQL的一个子集(HQL)

二、Hive的体系架构
BigData-13:Hive
三、安装和配置Hive
安装模式:
)嵌入模式:不需要使用MySQL,使用Hive自带的Derby数据库存储Hive的元信息
)本地模式、远程模式:都需要MySQL

准备工作:
1、解压 tar -zxvf apache-hive-2.3.0-bin.tar.gz -C ~/training/
2、设置环境变量 vi ~/.bash_profile

			HIVE_HOME=/root/training/apache-hive-2.3.0-bin
			export HIVE_HOME

			PATH=$HIVE_HOME/bin:$PATH
			export PATH

核心的配置文件 conf/hive-site.xml

1、安装Hive的嵌入模式
特点:(1)使用自带的Derby
(2)只支持一个连接
(3)用于开发和测试
创建hive-site.xml

			<?xml version="1.0" encoding="UTF-8" standalone="no"?>
			<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
			<configuration>
				<property>
					<name>javax.jdo.option.ConnectionURL</name>
					<value>jdbc:derby:;databaseName=metastore_db;create=true</value>
				</property>
				
				<property>
					<name>javax.jdo.option.ConnectionDriverName</name>
					<value>org.apache.derby.jdbc.EmbeddedDriver</value>
				</property>	
				
				<property>
					<name>hive.metastore.local</name>
					<value>true</value>
				</property>	

				<property>
					<name>hive.metastore.warehouse.dir</name>
					<value>file:///root/training/apache-hive-2.3.0-bin/warehouse</value>
				</property>			
			</configuration>

初始化MetaStore:
schematool -dbType derby -initSchema

日志:

Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) or using Hive 1.X releases.

2、安装配置MySQL数据库
在虚拟机上安装MySQL:

			yum remove mysql-libs 
			rpm -ivh mysql-community-common-5.7.18-1.el7.x86_64.rpm
			rpm -ivh mysql-community-libs-5.7.18-1.el7.x86_64.rpm
			rpm -ivh mysql-community-client-5.7.18-1.el7.x86_64.rpm
			rpm -ivh mysql-community-server-5.7.18-1.el7.x86_64.rpm
			rpm -ivh mysql-community-devel-5.7.18-1.el7.x86_64.rpm  (可选,但还是装上,后面装HUE的时候会用到。)

启动MySQL:service mysqld start
或者:systemctl start mysqld.service

查看root用户的密码:cat /var/log/mysqld.log | grep password
登录后修改密码:alter user 'root'@'localhost' identified by 'root';

MySQL数据库的配置:
创建一个新的数据库:create database hive;
创建一个新的用户:
create user 'root'@'%' identified by 'root';

给该用户授权
grant all on hive.* TO 'root'@'%';
grant all on hive.* TO 'root'@'localhost' identified by 'root';

免费工具:http://www.mysqlfront.de/

3、本地模式、远程模式
创建hive-site.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
			<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
			<configuration>
				<property>
					<name>javax.jdo.option.ConnectionURL</name>
					<value>jdbc:mysql://localhost:3306/hive?useSSL=false</value>
				</property>				

				<property>
					<name>javax.jdo.option.ConnectionDriverName</name>
					<value>com.mysql.jdbc.Driver</value>
				</property>	

				<property>
					<name>javax.jdo.option.ConnectionUserName</name>
					<value>hiveowner</value>
				</property>	

				<property>
					<name>javax.jdo.option.ConnectionPassword</name>
					<value>Welcome_1</value>
				</property>					
			
			</configuration>

四、(最重要)Hive的数据模型
1、内部表:类似MySQL、Oracle中表
默认的列的分隔符是:tab键

举例:创建一个员工表 emp表
数据 7654,MARTIN,SALESMAN,7698,1981/9/28,1250,1400,30

 create table emp
			  (empno int,
			   ename string,
			   job   string,
			   mgr   int,
			   hiredate string,
			   sal   int,
			   comm  int,
			   deptno int
			  );

创建一个员工表 emp1表,并且指定分隔符是:逗号

  		  create table emp1
  		  (empno int,
  		   ename string,
  		   job   string,
  		   mgr   int,
  		   hiredate string,
  		   sal   int,
  		   comm  int,
  		   deptno int
  		  )row format delimited fields terminated by ',';			  

导入数据:
insert语句
load语句:相当于ctrl+x
(1)导入HDFS的数据 load data inpath '/scott/emp.csv' into table emp;
(2)导入本地Linux的数据:load data local inpath '/root/temp/emp.csv' into table emp1;

客户端的静默模式:不打印日志

2、分区表:提高性能
举例:创建一个分区表,根据部门号deptno

			  create table emp_part
			  (empno int,
			   ename string,
			   job   string,
			   mgr   int,
			   hiredate string,
			   sal   int,
			   comm  int
			  )partitioned by (deptno int)
			  row format delimited fields terminated by ',';

往分区表中插入数据:子查询

insert into table emp_part partition(deptno=10) select empno,ename,job,mgr,hiredate,sal,comm from emp1 where deptno=10;
insert into table emp_part partition(deptno=20) select empno,ename,job,mgr,hiredate,sal,comm from emp1 where deptno=20;
insert into table emp_part partition(deptno=30) select empno,ename,job,mgr,hiredate,sal,comm from emp1 where deptno=30;

3、外部表:只定义表结构,数据保存在HDFS的某个目录下

		create external table ext_student
		(sid int,sname string,age int)
		row format delimited fields terminated by ','
		location '/students';

4、桶表:类似Hash分区
根据员工的职位job建立桶表

	    create table emp_bucket
		(empno int,
		 ename string,
		 job string,
		 mgr int,
		 hiredate string,
		 sal int,
		 comm int,
		 deptno int
		)clustered by (job) into 4 buckets
	    row format delimited fields terminated by ',';

需要设置环境变量:set hive.enforce.bucketing = true;
插入数据
insert into table emp_bucket select * from emp1;

5、视图:View
() 是一个虚(不存数据)表
(
) 作用:简化复杂的查询

		     create view view10
			 as
			 select * from emp1 where deptno=10;

() 补充:物化视图可以缓存数据
)补充:如何判断提高了性能? ----> 重点讲:关系型数据库(Oracle)、Hive类似方式
----> SQL执行计划

五、执行Hive的查询:执行SQL(HQL)
注意:HQL是SQL的一个子集
创建部门表

	create table dept
	(deptno int,dname string,loc string)
	row format delimited fields terminated by ',';

load data local inpath '/root/temp/dept.csv' into table dept;

1、查询所有的员工信息
select * from emp1;

2、查询员工信息:员工号 姓名 月薪 部门号
select empno,ename,sal,deptno from emp1;

3、多表查询

	   select dept.dname,emp1.ename
	   from emp1,dept
4、子查询:只支持from和where子句中的子查询
	查询部门名称是SALES的员工信息
		select *
		from emp1
		where emp1.deptno in (select deptno from dept where dname='SALES');
5、条件函数(条件表达式,就是一个if...else...语句)
	if
	coalesce
	case... when...
	
	  使用decode函数实现(oracle数据库)
		  select empno,ename,job,sal "Before",
		         decode(job,'PRESIDENT',sal+1000,
				            'MANAGER',sal+800,
							sal+400) "After"
		  from emp;

需求:做一个报表,列出涨前和涨后的工资
按照员工的职位来涨工资:总裁:1000 经理:800 其他:400

			  select empno,ename,job,sal,
			         case job when 'PRESIDENT' then sal+1000
					          when 'MANAGER'then sal+800
							  else sal+400
			         end
			  from emp1;
			7369	SMITH	CLERK		800		1200
			7499	ALLEN	SALESMAN	1600	2000
			7521	WARD	SALESMAN	1250	1650
			7566	JONES	MANAGER		2975	3775
			7654	MARTIN	SALESMAN	1250	1650
			7698	BLAKE	MANAGER		2850	3650
			7782	CLARK	MANAGER		2450	3250
			7788	SCOTT	ANALYST		3000	3400
			7839	KING	PRESIDENT	5000	6000
			7844	TURNER	SALESMAN	1500	1900
			7876	ADAMS	CLERK		1100	1500
			7900	JAMES	CLERK		950		1350
			7902	FORD	ANALYST		3000	3400
			7934	MILLER	CLERK		1300	1700

六、使用JDBC查询Hive

public class JDBCUtils {

	//定义Hive的Driver
	private static String driver = "org.apache.hive.jdbc.HiveDriver";
	//Oracle: oracle.jdbc.OracleDriver
	
	//URL地址
	private static String url = "jdbc:hive2://192.168.157.111:10000/default";
	
	//注册Driver
	static{
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	//获取链接
	public static Connection getConnection(){
		try{
			return DriverManager.getConnection(url);
		}catch(Exception ex){
			ex.printStackTrace();
		}
		return null;
	}
	
	//释放资源
	//问题:能不能通过Java代码去干预GC?
	public static void release(Connection conn,Statement st,ResultSet rs){
		if(rs != null){
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}finally{
				rs = null;
			}
		}
		if(st != null){
			try {
				st.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}finally{
				st = null;
			}
		}
		if(conn != null){
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}finally{
				conn = null;
			}
		}
	}
	
}
public class TestHive {

	public static void main(String[] args) {
		//查询: select * from emp1;
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try{
			conn = JDBCUtils.getConnection();
			st = conn.createStatement();
			
			//执行SQL
			rs = st.executeQuery("select * from emp1");
			while(rs.next()){
				String ename = rs.getString("ename");
				System.out.println(ename);
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}finally{
			//释放资源
			JDBCUtils.release(conn, st, rs);
		}
	}
}

七、Hive的自定义函数:本质是Java程序
1、UDF:User Define Function
2、封装业务逻辑

3、举例
(1)实现关系型数据库中concat函数

(2)根据员工的薪水,判断薪水的级别
() sal < 1000 ----> Grade A
(
) 1000<=sal <3000 —> Grade B
(*) sal >=3000 —> Grade C

4、部署我们jar包(自定义函数)
把jar加入Hive的Classpath
add jar /root/temp/myudf.jar;

为自定义函数创建别名

	 create temporary function myconcat as 'udf.MyConcatString';
	 create temporary function checksal as 'udf.CheckSalaryGrade';

数据分析引擎:Pig

一、什么是Pig?Pig的体系架构
1、是一个翻译器,把PigLatin语句 ----MapReduce
从0.17开始,支持Spark

2、由Yahoo开发

二、Pig的数据模型

三、Pig的安装和配置(非常简单)
两种运行的模式
1、本地模式:操作本地Linux的文件系统、类似Hadoop的本地模式

命令:pig -x local

日志: Connecting to hadoop file system at: file:///

2、MapReduce模式(集群模式): 把PigLatin语句转换成MapReduce提交Hadoop上运行
命令:bin/pig
日志:Connecting to hadoop file system at: hdfs://bigdata111:9000

配置一个环境变量

		PIG_CLASSPATH ---> 指向Hadoop的配置文件的目录
		PIG_CLASSPATH=$HADOOP_HOME/etc/hadoop
		export PIG_CLASSPATH

四、使用PigLatin语句来分析数据

五、Pig的自定义函数

相关文章: