Hive、hadoop命令基本使用

一、hadoop中HDFS的基本命令

   1、Hadoop启动服务命令

      (1)逐个启动hadoop服务:

1、sbin/hadoop-daemon.sh start namenode
2、sbin/hadoop-daemon.sh start datanode
3、sbin/hadoop-daemon.sh start secondarynamenode
4、sbin/yarn-daemon.sh start resourcemanager
5、sbin/yarn-daemon.sh start resourcemanager
6、sbin/mr-jobhistory-daemon.sh start historyserver

      (2)总体启动hadoop服务:

             前提条件:ssh免密登陆

ssh免密登录的方法:
第一步:ssh-keygen -t rsa               ------------ 本机生成 公钥与私钥(一路回车即可)
第二步:ssh-copy-id 主机名               ------------ 将本机生成的公钥传输到目标机器上,本机远程登陆该机器可以免密
------------------------------------ 如果提示没有ssh 命令 --------------------------
执行  sudo yum -y install openssh-clients

 

         图解: 

          总体启动hadoop服务:

=========================== 第一种方法 ====================================
sbin/start-dfs.sh        -------- 启动NameNode、datanode、secondarynamenode
sbin/start-yarn.sh         ------ 启动resourcemanager、nodemanager
sbin/mr-jobhistory-daemon.sh start historyserver   ------- 启动历史服务
=========================== 第二种方法:全部启动 ====================================
sbin/start-all.sh
sbin/mr-jobhistory-daemon.sh start historyserver

      (3)关闭hadoop服务:

1、kill -9 进程号
2、sbin/hadoop-daemon.sh stop ...
3、sbin/stop-dfs.sh   sbin/stop-yarn.sh 
4、sbin/stop-all.sh       ------------- 一次全部关闭

       (4)查看已启动的hadoop服务:

命令: jps

   2、web查看hadoop信息

                   http://ai07-server1:50070                ----------- HDFS文件(其中 ai07-server1是主机名,视情况而定)

                   http://ai07-server1:8088                  ----------- 查看yarn平台

                   http://ai07-server1:19888                ----------- 查看HDFS日志文件

               

   3、bin/hdfs dfs命令:

      (1)bin/hdfs dfs的所有命令:

  •                hadoop目录下:命令  bin/hdfs dfs

      (2)常用的HDFS命令:

                      特点:与linux命令及其相似        

hadoop中hdfs文件操作命令:hadoop 目录下执行
	格式:bin/hdfs dfs -命令  [选项] [参数]
----------------------------------------------------------------------------------
1、上传文件到hdfs系统中:bin/hdfs dfs -put linux路径 hdfs路径     ------- 注意  hdfs 路径 不要忘记 / 。
    例:bin/hdfs dfs -put /etc/passwd /
2、从hdfs上下载文件: bin/hdfs dfs -get hdfs路径 linux路径
3、bin/hdfs dfs -mkdir -p 目录路径
4、bin/hdfs dfs -rm -r 目录/文件路径
4、bin/hdfs dfs -ls -R 目录路径

二、Hive简介 

hive的概念:数据仓库软件
hive的本质:用HDFS存储数据,用SQL语句操作MapReduce来计算,
hive的作用:用SQL语句分析处理 分布式系统(HDFS)文件
hive的家目录:数据存储在在HDFS文件系统下:/user/hive/warehouse是hive的家目录,而linux系统中hive文件夹
             不储存数据,元数据存储到关系型数据库(RDBMS)上,并不在本地。
    bin/hdfs dfs -mkdir /tmp 
    bin/hdfs dfs -mkdir -p /user/hive/warehouse   ------ 创建hive的HDFS家目录,用于存储数据用于分析
----------------------------------------------------------------------------------------------
hive的目录结构(HDFS路径)
/user/hive/warehouse	/ai7.db			/student	/student.txt
默认工作目录			数据库目录		表目录		表里的数据文件

 

  •     数据库与数据仓库的区别: 
RDBMS
------------------------------------------------------------------
1、Relation Database Management System:关系型数据库管理系统,简称数据库
2、OLTP:在线事务处理
	-》响应速度快
	-》低延迟
Hive
---------------------------------------------------------------------
1、数据仓库软件
2、使用SQL读、写和管理存储在分布式文件系统上的大数据集
3、OLAP:在线分析处理
	-》延迟高
	-》响应速度慢
	-》重在分析海量数据
4、Hive是构建在Hadoop之上的:用到了存储和计算
5、不是分布式程序

三、Hive体系架构

        Hive体系架构图解

     hive与关系型数据库mysql应用场景示例:

 

 

四、Hive的基本命令

                   https://blog.csdn.net/qq_16555103/article/category/8592178   ------------ mySQL的sql语句

1、数据库操作命令和常用命令

1、启动hive使用命令:bin/hive
2、退出Hive shell命令窗口使用:quit; 或 exit;
3、数据库操作
	-》显示有哪些数据库
		- show databases;
	-》创建数据库
		- create database if not exists ai7;
	-》使用指定数据库
		- use ai7;
	-》删除数据库
		- drop database ai7 CASCADE;       ----------强制删除非空数据库
		hive> drop database ai7;
		
		FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. 
		InvalidOperationException(message:Database ai7 is not empty. One or more tables exist.)
4、描述表的信息
	-》desc student;			简单描述
	-》desc extended student;	详细描述,但是无格式
	-》desc formatted student;	详细描述,有格式
5、查看hive集成(自带)分析函数
	-》show functions;
6、查看函数怎么使用
	-》desc function upper;
	-》desc function extended upper;

2、表的操作命令

-------------------------------------- 简介 --------------------------------------
        -》显示所有表
		- show tables;
	-》创建表的操作
		- create table student2(
                                id int, 
                                name string, 
                                money double)row format delimited fields terminated by '\t';
		- 从row format开始是指定表的分隔符,hive表默认的分隔符是'\001'
	-》向student表添加数据
		- load data local inpath '/opt/datas/student.txt' into table student;
	-》查询数据
		- select * from student;
	-》如果加载的数据在select的时候,全部显示:NULL,错误原因如下:
		- 由于文件的分隔符 和 Hive表的分隔符不一致导致的
		- 错误操作演示:
			1. 建表
			create table student2(
                                id int, 
                                name string, 
                                money double)row format delimited fields terminated by '\t';
			2. 加载数据
			load data local inpath '/opt/datas/student.txt' into table student2;
			3. 查询数据
			select * from student2;
			
			OK
			NULL    NULL
			NULL    NULL
			NULL    NULL
			NULL    NULL
			NULL    NULL
			
			由于student.txt文件的分隔符是'\t',而student2表的分隔符是' ',所以导致数据加载失败
	-》删除表
		- drop table student2;
--------------------------------------- 表操作详情 -------------------------------------
一、在mysql的meta 数据库下:                                          ------- meta 存储的是 元数据。
	DBS ----- database
	存储在hive中创建的数据库的信息。
	TBLS------ tables   存储在hive中创建的数据表信息                        
二、hive工作目录下 显示 数据库 与 列名(header):
	https://blog.csdn.net/qq_16555103/article/details/87926120   ----- 第四节与第五节
三、查看表的描述信息:
	desc 表名;
	desc formatted 表名;       # 表信息的详细信息
 	MANAGED_TABLE  管理表内部表
	show functions;    查看hive自带的分析函数
	desc function [extended] 函数名;	查看函数描述信息
四、创建表的三种方式:
	注意:创建表只是创建表的结构,创建之后表仍然是空的,需要用load 方法从本地或者hdfs文件系统中加载数据。
   ================ 第一种方式:普通方式
    (1) 普通方式创建表:内部表、外部表、分区表
	1、内部表: MANAGED_TABLE     
            特点:内部表如果删除drop,hdfs内部数据与metastore中元数据 一起删除
	      create table student(        -------- student: 表名
	          id int,
                  name string,           
                  sal double       --------- 句末 没有 ,
                  )row format delimited fields terminated by '\t';         #   规定 列的 分隔符。
例:
create table emp(
empno int comment '员工编号',
ename string comment '员工姓名',
job string comment '员工职位',                 #  comment  后面  是 注释,不会写入数据库。
mgr int comment '领导编号',
hiredate string comment '入职时间',
sal double comment '薪资',
comm double comment '奖金',
deptno int comment '部门编号'
)
row format delimited fields terminated by '\t';	

	2、外部表: EXTERNAL_TABLE
	      特点:① 外部表(外部表可以select,在web端不显示 )如果删除,只有metastore中元数据删除,location的源数据不删除。
               ② 外部表与MANAGED_TABLE内部表共用一份数据,location指定的是内部表的数据路径,如果内部表数据变化,外部表的数据也会变化
               ③ 相当于创建了一个链接,用于读取内部表的信息
	      创建外部表的方法:
	          开头:external 关键字
	          结尾: loacation ‘路径’
          查询表类型方法:desc formatted 表名;
例:
create external table student1(                     
id int,  
name string     
)row format delimited fields terminated by '\t' 
location 'path';  #  path 指的是hdfs文件系统的路径,例如:/user/hive/warehouse/hadoop6.db/student 指定的是表名,不是表里面的文件。
	     ------- Table Type:     EXTERNAL_TABLE
	3、分区表:
          适用:通常用于时间分组的表。
          目的:提高 select where的执行效率。
	      内部表和外部表都可以作分区表。在末尾加上 :  
          partitioned by (data string,age string) #data 、age是分区字段,可以自定义的,后面是数据类型。  # 这是一个二级的分区表,它的关系是递进关系。
例:
 create table student_part2(                    
 id int,
 name string,
 age string
)
partitioned by(`date` string)                #                 这只是创建了一个分区空表(data字段 相当于一个目录)。需要加载。
row format delimited fields terminated by '\t';	
	分区表加载数据:
load data local inpath '/home/hadoop/ibeifeng/emp.txt' into table emp_part partition(`date`='20181129'); 
load data local inpath '/home/hadoop/ibeifeng/emp.txt' into table emp_part partition(`date`='20181130');   #  emp_part 目录下有两个目录 :data=20181129、data=20181130。
	查询分区表格:
select * from emp_part where `date`='20181129';        #  查询分区表格。
select * from emp_part;                  # 查询所有。
	分区表的目的:
	    提高查询效率。
	

 

分区表的实例:
创建分区表:
create table log(
id int,
age int,
address double
)partitioned by(day string)
row format delimited  fields terminated by '\t';
分区表加载数据:
load data local inpath '/opt/dataValues/student.txt' into table log partition(day='2019.03.03');
load data local inpath '/opt/dataValues/student.txt' into table log partition(day='2019.03.04');
查看数据:
select * from log;                             --------- 查询log表下所有信息
select * from log where day='2019.03.03';      --------- 引用分区表查询

 

 

    ================ 第二种创建表的方式:子查询方式(as select)    
        (2)、子查询的方式创建表: as select    有结构也有数据
           本质:相当于将后面select 语句查询的结果赋值给前面创建的表
	create table 表名1 as select 列名 from 表名2 [where ...];
    ================ 第三种创建表的方式:like方式   
	(3)、like方式:
	create table 表名1 like 表名2;
	复制表的结构赋予一张新的表,并没有数据。

五、删除表:
	1、清空表(不删除表结构,只清空数据):表结构还在,元数据信息还在
	truncate table test;
	2、删除表:所有数据删除
	drop table 表名;
六、修改表名:       alter :   改变
	alter table student rename to test;
七、给表添加一个列
	alter table test add columns(addr string);                            #   test: 表名
	alter table test add columns(age int comment 'age');    # 添加注释。
		                  #添加的列名  # 列的类型
八、修改列名和类型和顺序
	alter table test change age age1 string;
		                     # 列名 # 修改后的列名  # 类型
	alter table test change age age1 string first;     #   修改后调到第一名。
	alter table test change age age1 string after 列名1;     #   修改后调到列名1之后。

九、替换列:是全表替换
	alter table test replace columns(age string,gg string);
		用  括号中 的列 全表 替换。
	alter table test replace columns(dd string);
十、不启动hive操作	
	0:查看帮助信息	
	hive 的帮助信息 bin/hive -help
	1:指定登录到哪个数据库
	bin/hive --database hadoop6
	2:指定一条sql语句,必须要用  引号  引起来
	bin/hive -e 'show databases'
	3:将输出结果进行重定向到某个文件
	bin/hive -e 'show databases' >> a.txt 
	4:bin/hive -f a.sql 
	      vi a.sql
	      select * from hadoop6.test;     #     要指定数据库 。
 	5:bin/hive --hiveconf hive.cli.print.current.db=false;    


3、HIVE上传与下载数据 

十一、hive数据上传与下载:load 方法
	1、上传:
	   (1.1)本地加载数据不覆盖:
	load data local inpath 'linux路径' into table 表名;       # 有分区的表用partition。	
	   (1.2)本地加载覆盖(hdfs文件系统同理):在 into 前 加上 overwrite
	load data local inpath 'linux路径' overwrite into table 表名;
           (1.3)HDFS 加载数据:
                特点:会剪切HDFS的文件至HIVE的家目录中
	load data inpath 'hdfs路径' [overwrite] into table 表名; 
	  (2)利用子查询的方式导入数据: 
	        子查询的方式创建表: as select    
	create table 表名1 as select 列名 from 表名2;       # 有结构也有数据
	  (3)利用 insert 方法:
	        特点:insert 的 表 必须存在!
                本质:读取已存在的源表信息添加到已存在的表格中(区别于load data加载的本质)
	insert into 表名 select * from 表名2;     ---- 追加
	insert overwrite into 表名 select * from 表名2;   ---- 覆盖
          (4) bin/hdfs dfs -put   ------ 传至表目录下
	2、下载导出数据:  local 表示 导出 到 本地 还是 hdfs 文件系统。
	    (1)insert overwrite 命令
            insert overwrite [local] directory 'path' select语句; ----- 没有 列分隔符。
             特点:结果是一个目录,目录下的文件是保存的数据,会覆盖以前数据文件
	        指定分割符的命令: 加上之前创建 表格时 的 分隔符 语句。 
	        ① 导入本地:insert overwrite local directory 'path' row format delimited fields terminated by '\t' select语句;
                ② 导入HDFS:   去掉 local即可
                        insert overwrite directory 'path' row format delimited fields terminated by '\t' select语句;
	    (2)HDFS 文件系统下载: 
		bin/hdfs dfs -get 'hdfs路径' 'linux路径'
	    (3)bin/hive -e 或 -f 'sql语句' > a.txt 或者 >> a.txt      ------------------  注意 用这种方法 后面sql 语句要用 ‘’引起来。
		例:bin/hive -e 'select * from hadoop6.emp' > '/home/hadoop/ibeifeng/emp.ttttt'  -------------- hadoop6.emp 指定 hadoop6库下的 表格 emp。
------------------------------------------------------------------------------------------------
        3、sqoop                ------ 详情在本章下文
        -》数据导入导出的工具
        -》关系型数据库(MYSQL) <-> HDFS(Hive)  /user/hive/warehouse/库名/表目录名/ 
          
 
十二、上传数据中正则表达式的用法:
	 原因:上传内容复杂的数据
	上述 "row format delimited fields terminated by '\t'" 只是定义分隔符是 tab制表符,并不能作为复杂数据上传的的分隔符,例:
"27.38.5.159" "-" "31/Aug/2015:00:04:37 +0800" "GET /course/view.php?id=27 HTTP/1.1" "303" "440" - "http://www.ibeifeng.com/user.php?act=mycourse" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" "-" "learn.ibeifeng.com"

           (1)解决方法:用正则进行模糊匹配,将上述分隔符语句替换为:
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'        #  固定用法
WITH SERDEPROPERTIES (
  "input.regex" = "正则表达式"   # 例:(\"[^ ]*\") (\"-|[^ ]*\") (\"[^\]]*\") (\"[^\]]*\") (\"[0-9]*\") (\"[0-9]*\") (-|[^ ]*) (\"[^ ]*\") (\"[^\"]*\") (\"-|[^ ]*\") (\"[^ ]*\")
)
STORED AS TEXTFILE;         #   指定 文件类型

实例:
创建表格:
CREATE TABLE apachelog (
remote_addr string,
remote_user string,
time_local string,
request string,
status string,
body_bytes_set string,
request_body string,
http_referer string,
http_user_agent string,
http_x_forwarded_for string,
host string
 )                                        #   创建表格语句结束
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'                                 #  指定上传数据的  正则表达式 。
WITH SERDEPROPERTIES (
  "input.regex" = "(\"[^ ]*\") (\"-|[^ ]*\") (\"[^\]]*\") (\"[^\]]*\") (\"[0-9]*\") (\"[0-9]*\") (-|[^ ]*) (\"[^ ]*\") (\"[^\"]*\") (\"-|[^ ]*\") (\"[^ ]*\")"
)
STORED AS TEXTFILE;	
上传数据:
load data local inpath 'moodle.ibeifeng.access.log' into table apachelog;
select * from apachelog limit 1;        # limit 指的是只查询一行。

	(2)正则表达式在搜索(select  ...  where ... )用法:
	命令:select * from 表名 where 列名 rlike ‘正则表达式' ;                        # rlike 即正则表达式。
例:select * from emp where hiredate rlike  '^\\d{4}-\\d{1}-\\d{1}$';        (注意,linux系统中正则要用转义符 \ 来 转义 \d)。

4、HIVE函数使用 

十三、查看内置函数的命令
	1、show functions;     # 列出所有的 内置函数。
	2、desc function 函数名;   # 显示某个函数的描述信息。
	3、显示某个函数的扩展信息(即带例子):desc function extended 函数名;

十四、hive 函数:
   1、常见的内置函数:
	(1)substr  # 截取字符串  
	(2)round  # 四舍五入
	(3)floor  # 向下取整   ceil  # 向上取整
	(4)拼接字符串: concat
	(5)字符串长度:length
	(6)去空格 :trim
        (7)row_number()、rank()
   2、hive的分析函数(也叫窗口函数):  over
  •       over() 窗口函数的用法: 会增加一个新列
over 分析函数又称窗口函数(具有分组、排序等功能操作,partition by 区别于 group by)
     本质:将表中的某些列数据提取出来作为一个窗口进行分组排序等操作后用 前面的函数 计算并将计算值添加至新列中。 
     partition by 窗口分区  group by 源表数据分组
=========== over()函数应用的实例 =================
员工表:
create table emp(
empno int comment '员工编号',
ename string comment '员工姓名',
job string comment '员工职位',
mgr int comment '领导编号',
hiredate string comment '入职时间',
sal double comment '薪资',
comm double comment '奖金',
deptno int comment '部门编号'
)
row format delimited fields terminated by '\t';
------------------------------------------------------------------------------------------
# emp表的数据如下
emp.empno           emp.ename            emp.job 		emp.mgr emp.hiredate    emp.sal 	emp.comm        emp.deptno
7369    		SMITH   	CLERK   		7902    1980-12-17      800.0  		NULL    		20
7499    		ALLEN   	SALESMAN                7698    1981-2-20       1600.0 		300.0   		30
7521    		WARD    	SALESMAN                7698    1981-2-22       1250.0 		500.0   		30
7566    		JONES   	MANAGER 		7839    1981-4-2        2975.0 		NULL    		20
7654    		MARTIN  	SALESMAN                7698    1981-9-28       1250.0 		1400.0  		30
7698    		BLAKE   	MANAGER 		7839    1981-5-1        2850.0 		NULL    		30
7782    		CLARK   	MANAGER 		7839    1981-6-9        2450.0 		NULL    		10
7788    		SCOTT   	ANALYST 		7566    1987-4-19       3000.0 		NULL    		20
7839    		KING    	PRESIDENT               NULL    1981-11-17      5000.0 		NULL    		10
7844    		TURNER  	SALESMAN                7698    1981-9-8        1500.0 		0.0     		30
7876    		ADAMS   	CLERK   		7788    1987-5-23       1100.0 		NULL    		20
7900    		JAMES   	CLERK   		7698    1981-12-3       950.0  		NULL    		30
7902    		FORD    	ANALYST 		7566    1981-12-3       3000.0 		NULL    		20
7934    		MILLER  	CLERK   		7782    1982-1-23       1300.0 		NULL    		10
--------------------------------------------------------------------------------------
问题一:查询 所有 员工编号 为 10 的员工 并按照 降序排列:
命令: select * from emp where deptno='10' order by sal desc;     #  desc 表示降序 (默认升序)。
命令2: select ename,sal,deptno from emp where deptno='10' order by sal desc;    # 只显示 员工编号、薪资、部门编号。
问题二:将每个部门最高的薪资显示在最后一列:
命令:select ename,empno,sal,deptno,max(sal) over(partition by deptno order by sal desc) as xin_ from emp;
									        # as  临时给最后一行取一个 列名。
          #  over 分析函数(具有分组、排序等功能操作,partition by 区别于 group by)
问题三:将每个部门最后一列显示唯一编号( row_number()、rank() ):
命令:select ename,empno,sal,deptno,row_number() over(partition by deptno order by sal desc) as xin_ from emp;
                                                                # row_number()函数是 行号 排名,即使有大小相同的数据 名次不同 ,区别于 rank() 函数。
命令2:rank函数: select ename,empno,sal,deptno,rank() over(partition by deptno order by sal desc) as xin_ from emp;
问题四:获取每个部门薪资最高的前两位:
思路:分组(over(partition by ))排序 后 取值 ,即在问题三的结果上取值(子查询派生表(虚拟表必须有别名,这里取别名时 不用as))。
命令: select ename,empno,sal,deptno from(select ename,empno,sal,deptno,rank() over(partition by deptno order by sal desc) as xin_ from emp) tmp where xin_ <3;                                                                                                                                                                                                                                                                              # tmp 是派生表 临时的名字,必须有。
-----------------------------------------------------------------------------------------
    3、聚合函数:count(计数) 、sum、max、min、avg、group by、where(过滤关键字)
                having(筛选关键字,只能在select语句中使用,可以与where共同使用,且先执行 where 后执行 having)
    例:
        select count(*) as line from emp;
        select sum(sal) as total_sal from emp;
-----------------------------------------------------------------------------------------
    4、常见的HQL语句、关键字:where、limit 、distinct、between and 
    where   筛选
    例:select * from emp where sal > 3000;   筛选薪水大于3000 。
    limit  限制次数
    select * from emp limit 1; 读取 一行
    distinct  去重:
    select distinct * from emp;     去重
    is null 空值 is not null 非空值 
    between and :
    select * from emp where sal between 2000 and 3000;       闭区间
    或者 select * from emp where sal >= 2000 and sal <= 3000;
-----------------------------------------------------------------------------------------
    5、链表:join
	  (1)等值链表:join  ------  共同拥有的会出现
	  例:A表:                           B表:
	        id	name                    id	age
	        1	张三		1	18
	        2	李四		2	19
	        4      王五		3	21
	   命令:select a.id,a.name,b.id,b.age from A a join B b on a.id=b.id;              (  a、b分别是A的别名和B的别名 )
	  (2)左链接:left join  ----- 以左表为 主表 ,没有的值用 null
	   命令:select a.id,a.name,b.id,b.age from A a left join B b on a.id=b.id; 
	  (3)右链接:right join 类似  左链接   
	  (4)全链接:full join 全部 合并,没有的值用 null
           命令:select a.id,a.name,b.city from tab_a a full join tab_b b on a.id=b.id;
    6、Hive中的排序函数:order by、 sort by、distribute by、cluster by
        set hive.exec.reducers.bytes.per.reducer=<number>   ---- 设置数据量
        set hive.exec.reducers.max=<number>                 ---- 设置总的reduce task
        set mapreduce.job.reduces=<number>                  ---- 设置当前job的reduce的数量
            例: set mapreduce.job.reduces=3;               ---- 设置当前job的reduce的数量为3
        (1)order by 全局排序
            Hive中的order by跟传统的sql语言中的order by作用是一样的,会对查询的结果做一次全局排序,所以说,只有hive的sql中制定了order by所有的数据都会到同一个reducer进行处理(不管有多少map,也不管文件有多少的block只会启动一个reducer)。但是对于大量数据这将会消耗很长的时间去执行。
            这里跟传统的sql还有一点区别:如果指定了hive.mapred.mode=strict(默认值是nonstrict),这时就必须指定limit来限制输出条数,原因是:所有的数据都会在同一个reducer端进行,数据量大的情况下可能不能出结果,那么在这样的严格模式下,必须指定输出的条数。
        (2)sort by 局部排序
            Hive中指定了sort by,那么在每个reducer端都会做排序,也就是说保证了局部有序(每个reducer出来的数据是有序的,但是不能保证所有的数据是有序的,除非只有一个reducer),好处是:执行了局部排序之后可以为接下去的全局排序提高不少的效率(其实就是做一次归并排序就可以做到全局排序了)。
        (3)distribute by和sort by一起使用
            ditribute by是控制map的输出在reducer是如何划分的,举个例子,我们有一张表,mid是指这个store所属的商户,money是这个商户的盈利,name是这个store的名字

        select mid, money, name from store distribute by mid sort by mid asc, money asc
        等价于:
        select mid, money, name from store cluster by mid sort by money
        我们所有的mid相同的数据会被送到同一个reducer去处理,这就是因为指定了distribute by mid,这样的话就可以统计出每个商户中各个商店盈利的排序了(这个肯定是全局有序的,因为相同的商户会放到同一个reducer去处理)。这里需要注意的是distribute by必须要写在sort by之前。
        (4)cluster by
            cluster by的功能就是distribute by和sort by相结合,注意:他只能正序排序且分区字段与排序子段必须相同
            如下:两个语句等价
            select mid, money, name from store cluster by mid  
            select mid, money, name from store distribute by mid sort by mid  

 十五、时间日期函数: ------------------  用 desc function extended 函数名;   -------- 查看用法!
             (5.1)获取当前时间的时间戳:
		select unix_timestamp();
		select unix_timestamp('2017-03-12 23:59:59');         #  获得指定日期的时间戳。
	     (5.2)抽取日期:
		select to_date('2017-03-12 23:59:59');       # 结果:2017-03-12
		抽取年份:
		select year('2017-03-12 23:59:59');             # 结果 : 2017
		抽取月份,天 :month、day
	     (5.3)日期之差:
		select datediff('2017-03-13','2017-03-12');    ----- 前面减去后面
	     (5.4)日期相加:date_add()   ------ select date_add('2009-07-30', 1)  # 后面只能是int
	     (5.5)日期相减:date_sub()  # 后面参数是 int。
	     (5.6)case when  then  when then else end 条件判断:
		例:select ename,deptno,case deptno when '10' then 'this patr is 10' when '20' then 'this patr is 20' else 'this patr is 30' end from emp;

 5、Hive常用的Linux Shell操作命令

1、--database 指定使用哪一个数据库
	-》示例:bin/hive --database ai7;
2、-e 允许在Linux命令行下执行Hive SQL语句
	-》示例1:bin/hive -e 'show databases'       ----------- sql语句需要加 ‘ ’
	-》示例2:bin/hive -e 'show databases;use ai7;select * from student'
	
		OK
		database_name
		ai7
		default
		Time taken: 1.52 seconds, Fetched: 2 row(s)
		OK
		Time taken: 0.074 seconds
		OK
		student.id      student.name
		1       zhangsan
		2       lisi
		3       wangwu
		4       zhaoliu
		5       dongqi
		Time taken: 0.712 seconds, Fetched: 5 row(s)
		
		注意:多个SQL语句之间,使用分号(;)隔开
3、> >> 用法:
	-》示例:bin/hive -e 'show databases;use ai7;select * from student' > /tmp/hive.file
		使用输出重定向符号,把查询结果写到/tmp/hive.file文件里
		>  覆盖
		>> 追加
4、-f 支持从一个文件里执行SQL语句
	-》示例:bin/hive -f /opt/datas/hive.sql
	-》hive.sql文件内容如下:
		show databases;
		use ai7;
		select * from student;
5、--hiveconf 启动hive时可以指定配置一个属性
	-》示例:bin/hive --hiveconf hive.cli.print.current.db=false
	-》注意:这个是临时修改,当hive shell退出时就会失效
	-》上面的临时修改不是很常用,我通常使用下面的set命令临时修改属性
		- 示例1:set hive.cli.print.current.db=false;
		- 示例2:set hive.cli.print.current.db; #查看属性值
5、--hivevar 传递参数
	-》示例:bin/hive --hivevar v_name='zhangsan' -f /opt/datas/hive.sql
	-》hive.sql文件内容如下:
		show databases;
		use ai7;
		select * from student where name='${hivevar:v_name}';

五、HIVE的运行模式

hiveserver2服务
----------------------------------------------------------------------
1、运行hive的三种方式
	-》CLI(Command Line Interface), bin/hive
	-》hiveserver2服务,hiveserver2类似于一个服务端,需要客户端(beeline)连接上之后,在客户端操作hive
	-》HWI(Hive Web Interface)忽略
2、演示如何使用hiveserver2使用hive(hive目录下执行)
	-》第一步:启动服务端 bin/hiveserver2
	-》第二步:启动客户端 方法一:① bin/beeline
		               ② - beeline> !connect jdbc:hive2://主机名:10000 用户名 密码
	                    方法二:bin/beeline -u jdbc:hive2://主机名:10000 -u 用户名 -p 用户密码
3、hiveserver2连接失败
	-》jps 把所有 RunJar进程全部杀死
	-》kill -9 pid
				
Fetch运行模式
-------------------------------------------------------------
1、Hive底层是基于Hadoop(HDFS + MapReduce)
2、执行mapreduce是非常慢的,因为启动很多进程,申请计算资源,这些都比较耗时
3、假如:我们只想执行一条简单的查询语句 select * from emp; 也要去执行mapreduce 的话,那效率非常低
4、Fetch模式可以把查询语句不涉及到计算的,都不需要执行mapreduce
5、Fetch的配置参数:

	  <property>
		<name>hive.fetch.task.conversion</name>
		<value>more</value>
		
		<description>
		  Expects one of [none, minimal, more].
		  Some select queries can be converted to single FETCH task minimizing latency.
		  Currently the query should be single sourced not having any subquery and should not have
		  any aggregations or distincts (which incurs RS), lateral views and joins.
		  0. none : disable hive.fetch.task.conversion
		  1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only
		  2. more    : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
		</description>
	  </property>
	  
	 
	1.none:执行任何的SQL语句都需要执行mapreduce,禁用了fetch模式
	2.minimal:select *,针对分区列进行过滤,limit 执行这些语句的时候不跑mapreduce
	3.more:select,过滤条件,limit,虚拟列,执行这些语句的时候不跑mapreduce
    
虚拟列
-------------------------------------------------------------------
1、INPUT__FILE__NAME  当前每一行的数据来源于哪个文件
2、BLOCK__OFFSET__INSIDE__FILE  每行首字母相对于文件起始位置的字节偏移量
   

六、sqoop 传输工具

1、数据的转换工具
2、关系型数据库 <-> HDFS,MYSQL -> Hive,Hive -> MYSQL
3、sqoop工具在传输数据的时候,底层使用的是mapreduce,只不过只用map task,没有使用reduce task。
  •  sqoop环境部署
1、和jDK、hadoop一样,将sqoop压缩包传至linux系统 /opt/softwares中 并解压到 /opt/moudles 目录下
2、跳转至 sqoop的conf配置目录下:
    复制并重命名:
        cp sqoop-env-template.sh  sqoop-env.sh
    配置sqoop-env.sh,修改内容如下:		
		export HADOOP_COMMON_HOME=/opt/modules/hadoop-2.7.3    ------ hadoop路径,由自己hadoop目录决定
		export HADOOP_MAPRED_HOME=/opt/modules/hadoop-2.7.3
		export HIVE_HOME=/opt/modules/hive-1.2.1-bin           ------ hive路径,由自己hadoop目录决定
5、将mysql驱动jar包复制至sqoop目录下的lib目录中:
    cp mysql-connector-java-5.1.27-bin.jar /opt/modules/sqoop-1.4.7.bin__hadoop-2.6.0/lib/
6、启动 bin/sqoop
------------------------------------------------------------------------------------------
        注意:如果期间报错将 hive目录lib下的 hive下的 hive-exec-1.2.1.jar 文件 复制到 sqoop的lib目录下:
        cp /opt/modules/hive-1.2.1-bin/lib/hive-exec-1.2.1.jar /opt/modules/sqoop-1.4.7.bin__hadoop-2.6.0/lib/            
  • sqoop常用的命令讲解
1、查看帮助命令:  命令后加 --help
    例:bin/sqoop list-databases --help
2、连接查看MYSQL数据库
     bin/sqoop list-databases --connect jdbc:mysql://ai7-server1:3306 --username root --password 123456
     sqoop通常语句格式: 用  \ 进行分割上诉命令

bin/sqoop list-databases \
--connect jdbc:mysql://ai7-server1:3306 \
--username root \
--password 123456
  • sqoop导入 HDFS数据
import 导入数据(mysql >>>>>> HDFS)
==================================== 把MYSQL里的数据直接导入到Hive目录下 ===================
# mysql建表
create table to_hdfs(
id int primary key not null,
name varchar(20) not null);

# mysql向to_hdfs表插入数据
insert into to_hdfs value(1,'zhangsan');
insert into to_hdfs value(2,'lisi');
insert into to_hdfs value(3,'wangwu');
insert into to_hdfs value(4,'zhaoliu');
insert into to_hdfs value(5,'dongqi');


# 把to_hdfs表的数据导入到HDFS   
bin/sqoop import \                                              ---------- 导入数据
--connect jdbc:mysql://主机名:3306/库名 \                        ---------- 连接mysql数据库的某个库
--username root \                                               ---------- 连接mysql数据库的 用户名
--password 123456 \
--table to_hdfs \                                               ---------- 连接mysql数据库的 to_hdfs 表
--num-mappers 1                                                 ---------- 定义map的数量为1

# 指定导入到HDFS上数据的分隔符
bin/sqoop import \
--connect jdbc:mysql://ai7-server1:3306/sqoop_test \
--username root \
--password 123456 \
--table to_hdfs \
--num-mappers 1 \
--fields-terminated-by '\t'

# 设置导入到HDFS的指定的目录下
bin/sqoop import \
--connect jdbc:mysql://ai7-server1:3306/sqoop_test \
--username root \
--password 123456 \
--table to_hdfs \
--num-mappers 1 \
--fields-terminated-by '\t' \
--target-dir '/to_hdfs'
================================== 把MYSQL里的数据直接导入到Hive表里 =======================
在hive建库,建表

#建库
create database school;

#建表
create table student(
id int,
name string
)
row format delimited fields terminated by '\t';

#使用sqoop把mysql to_hdfs里的数据导入到hive 的 student表中
bin/sqoop import \
--connect jdbc:mysql://ai7-server1:3306/sqoop_test \
--username root \
--password 123456 \
--table to_hdfs \
--num-mappers 1 \
--fields-terminated-by '\t' \
--direct \                                     -------------- 表示 mysql 快速查询
--hive-import \                                -------------- 声明 导入 hive 
--hive-database school \                       -------------- 声明 导入 hive的 school库                 
--hive-table student \                         -------------- 声明 导入 hive的 school库的student表
--delete-target-dir                            -------------- 删除默认的目录
  • sqoop导入 mysql数据 
export 命令演示,把HDFS上的数据导出到MYSQL
		
#在mysql的sqoop_test库下建表
create table from_hive(
id int primary key not null,
name varchar(20) not null);

#把student表的数据导出到mysql的from_hive表
bin/sqoop export \
--connect jdbc:mysql://ai7-server1:3306/sqoop_test \
--username root \
--password 123456 \
--table from_hive \
--num-mappers 1 \
--export-dir '/user/hive/warehouse/school.db/student' \      ------- 给定文件HDFS表目录
--input-fields-terminated-by '\t'                            ------- 给定导入mysql中的分隔符

七、HIVE分析小练习

            https://blog.csdn.net/qq_16555103/article/details/88190326    ---------  HIVE分析小练习

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值