我们先把Hive的安装包下载到Linux系统中,下载地址:http://archive.cloudera.com/cdh5/cdh/5/hive-1.1.0-cdh5.7.0.tar.gz。这里我们选择和前面Hadoop一样的cdh5.7.0的版本。
然后,我们需要把压缩包解压到“~/app/”目录下(个人习惯),然后在“/etc/profile”中配置Hive的环境变量。保存之后别忘了“source /etc/profile”。
export HIVE_HOME=~/app/hive-1.1.0-cdh5.7.0
export PATH=$HIVE_HOME/bin:$PATH
因为Hive中的元数据(Hive元数据就是Hive的一些基本的元素,主要包括hive表的基本属性:hive表的数据库名、表名、字段名称与类型、分区字段与类型;表的分区,分区的属性location等等)是存放在MySQL中的。所以我们需要事先在Linux环境中安装一个MySQL(具体安装步骤,网上特别多)。
(1)我们进入hive安装包下面的conf目录,先执行“cp hive-env.sh.template hive-env.sh”,然后“vi hive-env.sh”,打开文件进行修改。我们只需要添加一行HADOOP_HOME的路径即可,这里是你们自己的Hadoop安装路径。然后保存退出。
(2)我们还需要在conf目录下,新建一个配置文件,“vi hive-site.xml”,然后配置如下。
javax.jdo.option.ConnectionURL
jdbc:mysql://localhost:3306/sparksql?createDatabaseIfNotExist=true
javax.jdo.option.ConnectionDriverName
com.mysql.jdbc.Driver
javax.jdo.option.ConnectionUserName
root
javax.jdo.option.ConnectionPassword
password
(3)因为我们是用MySQL作为Hive元数据存储的,但是Hive里面没有自带MySQL驱动包,所以我们要下载mysql驱动包放到Hive的lib目录下。mysql驱动下载地址:mysql-connector-java-5.1.42-bin.jar (密码:xwq2)。
到Hive的bin目录下,执行“./hive”即可。
我们以词频统计为例,进行分析。
(1)首先新建一张表,create table hive_wordcount(context string); 这里context是字段名,string表示字符串类型。
创建成功后,我们可以执行"show tables",查看一下Hive中的表,验证一下。
好了,此时我们另一个终端,打开MySQL数据库,进入sparksql数据库中,我们会发现有特别多的数据表(存放的都是元数据信息)。其中TBLS表存放的是你Hive里面到底有哪些东西。我们查询一下TBLS这张表,“select * from TBLS;”
其中TBL_ID就是数据表的id,TBL_NAME就是数据表的名称。如果我们想查看这个表中的字段,我们可以执行“select * from COLUMNS_V2;”。
(2)这个时候我们要把本地文件中 (hello.txt) 中的数据加载到Hive中, 我们切换到hive端, 然后执行“load data local inpath '/home/Kiku/data/hello.txt' into table hive_wordcount;”,这里是从本地文件加载,如果是HDFS上的文件,去掉local即可。
注意:‘load data local inpath '/home/Kiku/data/' overwrite into table hive_wordcount’,意思是将目录下的所有文件都导入表中,并且覆盖原来的数据。
然后我们查看一下hive_wordcount这个表中的数据,“select * from hive_wordcount;”,发现已经有数据了。
(3)我们用sql语句进行词频统计,执行“select word, count(1) from hive_wordcount lateral view explode(split(context, ' ')) wc as word group by word;”,这里呢,lateral view explode(split(context, ' ')) wc as word就是:把每行的记录按照空格进行划分,划分出来的每个单词是wc,我们起个别名叫word。最后对word进行分组计数。运行结果如下:
我们可以发现,hive sql提交执行以后会生成MapReduce作业,并在YARN上运行。
(4)接下来,我们以员工表、部门表为例,进行一些统计分析。
首先我们准备两份数据,在“~/data/”目录下,新建一个emp.txt,“vi emp.txt”,作为我们的员工数据。
7369 SMITH CLERK 7902 1980-12-17 800.00 20
7499 ALLEN SALESMAN 7698 1981-2-20 1600.00 300 30
7521 WARD SALESMAN 7698 1981-2-22 1250.00 500 30
7566 JONES MANAGER 7839 1981-4-2 2975.00 20
7654 MARTIN SALESMAN 7698 1981-2-22 1250.00 500.00 30
7698 BLAKE MANAGER 7839 1981-5-1 2850.00 30
7782 CLARK MANAGER 7839 1981-6-9 2450.00 10
7788 SCOTT ANALYST 7566 1987-4-19 3000.00 20
7839 KING PRESIDENT 1981-11-17 5000.00 10
7844 TURNER SALESMAN 7698 1981-9-8 1500.00 0.00 30
7876 ADANS CLERK 7788 1987-5-23 1100.00 20
7900 JAMES CLERK 7698 1981-12-3 950.00 30
7902 FORD ANALYST 7566 1981-12-3 3000.00 20
7934 MILLER CLERK 7782 1982-1-23 1300.00 10
8888 HIVE PROGRAM 7839 1988-1-23 10300.00
分别是:员工编号、员工名称、员工岗位、员工的上级领导的编号、入职时间、工资、津贴(可以没有这个数据)、部门编号。数据和数据之间以“\t”进行分隔。
“vi dept.txt”,作为我们的部门数据。
10 ACCOUNTING NEW WORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
分别是:部门编号、部门名称、部门地点。同样的,数据和数据之间是以“\t”进行分隔的。
接下里,在Hive中创建两张数据表。
create table emp(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double,
deptno int
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
create table dept(
deptno int,
dname string,
location string
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t':因为文件中的数据之间是以"\t"进行分隔的,所以我们写入的是"\t"符号之间的数据。
然后向这两个表中插入数据。
load data local inpath '/home/Kiku/data/emp.txt' into table emp;
load data local inpath '/home/Kiku/data/dept.txt' into table dept;
我们做一个非常简单的测试,求每个部门的人数。
select deptno,count(1) from emp group by deptno;
结果如下
select empno, ename, sal, sal*12, comm, sal*12+comm from emp;
此时,会发现,奖金为NULL的时候,最后的年收入也是NULL,因为只要有NULL,那么最后结果也是NULL;这是我们应该把值为NULL的数据转化为0,参与计算。
select empno, ename, sal, sal*12, comm, sal*12+nvl(comm, 0) from emp;
select * from emp where comm is null;
select ename, job, sal, case job when 'PRESIDENT' then sal+1000 when 'MANAGER' then sal+800 else sal+400 end from emp;
select count(*), sum(sal), max(sal), min(sal), avg(sal) from emp;
通过explode把map集合中的元素,拆分成一行一行的
select explode (map(1, 'Tom', 2, 'Mary'));
3.5 等值连接:按部门统计 部门号、部门名称、人数
select d.deptno, d.dname, count(e.empno) from emp e, dept d where e.deptno=d.deptno group by d.deptno, d.dname;
注意:要查询的数据,如果不是聚合函数,那么就一定要加在group by之后
3.6 外连接【通过外连接可以对于连接条件不成立的记录仍然包含在最后的结果中】 left / right outer join
select d.deptno, d.dname, count(e.empno) from emp e right outer join dept d on e.deptno=d.deptno group by d.deptno, d.dname;
4.1 执行命令之后才可以以客户端的方式访问数据仓库
hive --service hiveserver2
4.2 JDBC操作数据库和JDBC操作MySQL数据库类似,只不过获取的数据库连接是HiveDriver
想了解更多的Hive sql的用法,请移步Hadoop Hive sql 语法详解。