Hive的操作

一、Hive DDL

官网参考链接 https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL

1.1 库操作

Create Database

CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
  [COMMENT database_comment]
  [LOCATION hdfs_path]
  [WITH DBPROPERTIES (property_name=property_value, ...)];

LOCATION 可以省略,默认存放在/user/hive/warehouse/库名.db目录下

Drop Database

DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE];

删除库时,是两步操作:

  1. 在mysql的DBS表中删除库的元数据

  2. 删除hdfs上库存放的路径

以上操作只能删除空库(库中没有表)!如果库中有表,是无法删除的,如果要强制删除,需要添加cascade关键字

Alter Database

ALTER (DATABASE|SCHEMA) database_name SET DBPROPERTIES (property_name=property_value, ...);   -- (Note: SCHEMA added in Hive 0.14.0)

ALTER (DATABASE|SCHEMA) database_name SET OWNER [USER|ROLE] user_or_role;   -- (Note: Hive 0.13.0 and later; SCHEMA added in Hive 0.14.0)
 
ALTER (DATABASE|SCHEMA) database_name SET LOCATION hdfs_path; -- (Note: Hive 2.2.1, 2.4.0 and later)

在改库的属性时,同名的属性会覆盖,不存在的属性会新增!

Read Database

-- 切换库
USE database_name;
-- 查看库的描述
desc database database_name;
-- 查看库的详细描述
desc database extended  database_name;
-- 查看库中的表
show tables in database_name;
-- 查看当前库下的表
show tables;

1.2 表

Create Table

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name 
-- 列的信息
[(col_name data_type [COMMENT col_comment], ...)] 
-- 表的注释
[COMMENT table_comment] 
-- 是否是分区表,及指定分区字段
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] 
[CLUSTERED BY (col_name, col_name, ...) 
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] 
[ROW FORMAT row_format] 
[STORED AS file_format] 
[LOCATION hdfs_path]
[TBLPROPERTIES]

1.管理表和外部表

在创建表时,如果加了EXTERNAL,那么创建的表的类型为外部表!

如果没有指定EXTERNAL,那么创建的表的类型为内部表或管理表!

区别:

①如果当前表是外部表,那么意味指hive是不负责数据生命周期管理的!如果删除了hive中的表,那么只会删除表的schame信息,而不会删除表目录中的数据!

②如果为管理表,意味着hive可以管理数据的生命周期!如果删除了hive中的表,那么不仅会删除mysql中的schame信息,还会删除hdfs上的数据

通常情况下,创建的都是外部表!

表是廉价的,数据是珍贵的!

1.1 管理表和外部表的转换

可以通过查看表的Table Type属性,来判断表的类型!

在hive中除了属性名和属性值,其他不区分大小写!

MANAGED_TABLE—>EXTERNAL_TABLE
alter table 表名 set TBLPROPERTIES('EXTERNAL'='TRUE')

EXTERNAL_TABLE—>MANAGED_TABLE
alter table 表名 set TBLPROPERTIES('EXTERNAL'='FALSE')

2.分区表

2.1 作用

分区表的目的是为了分散数据!将表的数据,按照一个指定的分区字段,分散到表目录的子目录中!

	作用: 在查询时,可以根据分区字段,过滤数据,减少查询时MR输入的数据量!
2.2 注意

​ 一旦一个表创建为了分区表,那么在向表中加载数据时,必须把数据加载到表的最后一级分区目录下!

​ 一旦一个表是分区表,那么会为每个分区目录下的数据自动添加所对应的分区的字段名和字段值!

​ 分区字段和普通的列的字段是不同的!

​ 分区目录的名称必须是分区字段名=分区字段值

1.2.3 创建

1.3.3.1 建表分区表

①创建一个一级分区(只有一个分区字段)表

create table t2(id int,name string,sex string) partitioned by(province string)

②准备数据

1^ATom^Amale
2^AJack^Amale
3^AMarry^Afemale

1.3.3.2put导入

  • 方式一 导入数据

put方式: 只能上传数据,无法对分区表生成元数据!
使用命令自动修复分区的元数据

msck repair table 表名
  • 方式二 上传数据后添加分区

上传数据

dfs -mkdir -p
 /user/hive/warehouse/dept_partition2/month=201709/day=11;
hive (default)> dfs -put /opt/module/datas/dept.txt  /user/hive/warehouse/dept_partition2/month=201709/day=11;

手动创建分区,不仅可以生成分区目录,还会生成分区的元数据

alter table 表名 add partition(分区字段名=分区字段值)
  • 方式三 创建文件夹后load数据到分区
load data [local] inpath '/datas/dept.txt' into [overwrite] table
 表名 partition(分区字段名=分区字段值,...);

load的方式不仅可以帮我们将数据上传到分区目录,还可以自动生成分区的元数据!

  • 查看表的分区元数据
show partitions 表名

1.3.3.3 load(load)

oad data local inpath '/home/atguigu/hivedatas/t2.data' into table t2 partition(province='guangxi')

load的方式不仅可以帮我们将数据上传到分区目录,还可以自动生成分区的元数据!

分区的元数据存放在metastore.PARTITIONS表中!

1.3.4删除分区

alter table 表名 drop patition(),patition()

删除分区一定会删除分区的元数据,如果表是管理表,还会删除分区目录!

1.3.5 多级分区表

表是一个分区表,但是有多个分区字段!

create table t3(id int,name string,sex string) partitioned by(province string,city string,area string)

加载数据:

 load data local inpath '/home/atguigu/hivedatas/t2.data' into table t3 partition(province='guangxi',city='nanning',area='buzhidao')

Drop Table

drop table [if exists] 表名

Read Table

查看表的描述

desc  表名

查看表的详细描述

desc extended 表名

格式化表的详细描述

desc formatted 表名

Alter Table

alter table 表名 set TBLPROPERTIES('属性名'='属性值')

Truncate

注意:Truncate只能删除管理表,不能删除外部表中数据

truncate table 表名;

二、Hive DML

官网参考链接https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML

2.1 数据导入

load

load data [local] inpath '数据路径' into table 表名 [partition]

带local:从本地将数据put到hdfs上的表目录!

不带local: 代表将hdfs上的数据,mv到hdfs上的表的目录!

insert

​ insert导入数据会运行MR程序,在特殊的场景下,只能使用insert不能用load!

​ 例如:

​ ①分桶

​ ②希望向hive表中导入的数据以SequnceFile或ORC等其他格式存储!

语法:

insert into | overwrite  table 表名 [partition()] values(),(),() | select 语句

insert into: 向表中追加写

insert overwrite: 覆盖写,清空表目录(hdfs层面,和外部表无关),再向表中导入数据

多插入模式:从一张源表查询,执行多条insert语句,插入到多个目的表

from 源表
insert xxxx 目标表1 select xxxx
insert xxxx 目标表2 select xxxx
insert xxxx 目标表3 select xxxx

示例:

from t3
insert overwrite table t31 partition(province='henan',city='mianchi',area='chengguanzhen') select id,name,sex 
where province='guangdong' and city='shenzhen' and area='baoan'
insert overwrite table t32 partition(province='hebei',city='mianchi',area='chengguanzhen') select id,name,sex 
where province='guangxi' and city='liuzhou' and area='buzhidao'
insert overwrite table t33 partition(province='hexi',city='mianchi',area='chengguanzhen') select id,name,sex 
where province='guangxi' and city='nanning' and area='buzhidao'

location

​ 建表时可以指定表的location属性(表在hdfs上的目录)。适用于数据已经存在在hdfs上了,只需要指定表的目录和数据存放的目录关联即可!

As Select

create table if not exists 新表 as select 字段... from 原始表;

import

​ import必须导入的数据是由export命令导出的数据!

IMPORT [[EXTERNAL] TABLE new_or_original_tablename [PARTITION (part_column="value"[, ...])]]
  FROM 'source_path'
  [LOCATION 'import_target_path']

要求: ①如果要导入的表不存在,那么hive会根据export表的元数据生成目标表,再导入数据和元数据

​ ②如果表已经存在,在导入之前会进行schame的匹配检查,检查不复合要求,则无法导入!

​ ③如果目标表已经存在,且schame和要导入的表结构匹配,那么要求要导入的分区必须不能存在!

2.2 数据导出

insert

命令:

insert overwrite [local] directory '导出的路径'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'  
select 语句;

带local导出到本地的文件系统,不带local代表导出到hdfs!

export

命令:

EXPORT TABLE tablename [PARTITION (part_column="value"[, ...])]
  TO 'export_target_path' [ FOR replication('eventid') ]

优势: 既导出数据还导出metastore(元数据,表结构)

​ 导出的数据和表结构可以移动到其他的hadoop集群或hive中,使用import导入!

Hadoop命令导出到本地

dfs -get /user/hive/warehouse/表名/    /output/

Hive Shell

(hive -f/-e 执行语句或者脚本 > file)

bin/hive -e 'select * from default.表名;'  > /output/;

三、Hive中的排序

1.Order by

​ Order by 代表全排序

​ 全排序: 对整个数据集进行排序! 要求只能有一个reduceTask!

select * from emp order by sal desc;
select * from emp order by job,sal desc;

2.Sort by

​ sort by代表部分排序

​ 部分排序: 设置多个reduceTask,每个reduceTask对所持有的分区的数据进行排序!

​ 每个分区内部整体有序!

①需要手动修改mapreduce.job.reduces,告诉hive我们需要启动多少个reduceTask

set mapreduce.job.reduces=3

②进行部分排序

insert overwrite local directory '/home/atguigu/sortby' select * from emp sort by deptno;

sort by只是指定排序的字段,无法控制数据按照什么字段进行分区!

3.Distribute by

​ 结合sort by一起使用!Distribute by必须写在sort by 之前! 先分区,再排序!用来指定使用什么字段进行分区!

​ 需求: 按照部门号,对同一个部门的薪水进行降序排序,每一个部门生成一个统计的结果文件!

​ 操作: 按照部门号进行分区,按薪水进行降序排序

insert overwrite local directory '/sortby' row format delimited fields terminated by '\t'  select * from emp Distribute by deptno sort by sal desc ;

4.Cluster by

​ cluster by是一种简化!

​ 如果sort by 和 distribute by的字段一致,且希望按照asc进行排序!那么可以简写为cluster by

distribute by sal sort by sal  asc  等价于   cluster by sal 

​ 如果使用了cluster by,不支持降序,只支持升序!

5.本地模式

​ MR以local模式运行!数据量小,比YARN上运行要快!

​ 设置:

set hive.exec.mode.local.auto=true;

四、函数的查看

注意: 用户自定义的函数是以库为单位!在创建这个函数时,必须在要使用的库进行创建!否则需要用库名.函数名使用函数!

查看所有的函数:

show functions

查看某个函数的介绍:

desc function 函数名

查看某个函数的详细介绍:

desc function extended 函数名

4.1NVL

4.1.1 介绍

nvl(value,default_value) - Returns default value if value is null else returns valuevaluenull值时,返回default_value,否则返回value

4.1.2 使用

一般用在计算前对null的处理上!

求有奖金人的平均奖金: avg聚集函数默认忽略Null

select avg(comm) from emp;

求所有人的平均奖金: 提前处理null值!

select avg(nvl(comm,0)) from emp;

4.2 字符串拼接函数

4.2.1 concat

描述:

concat(str1, str2, ... strN) - returns the concatenation of str1, str2, ... strN or concat(bin1, bin2, ... binN) - returns the concatenation of bytes in binary data  bin1, bin2, ... binN
Returns NULL if any argument is NULL

concat可以完成多个字符串的拼接!

一旦拼接的字符串中有一个NULL值,返回值就为NULL!

在concat拼接前,一定要先保证数据没有为NULL的!

4.2.2 concat_ws

描述:

concat_ws(separator, [string | array(string)]+) - returns the concatenation of the strings separated by the separator.

返回多个字符串或字符串数组的拼接结果,拼接时,每个字符串会使用separator作为分割

不受NULL值影响, NULL值会被忽略!

4.3 行转列函数

4.3.1含义

​ 行转列: 1列N行 转为 1列1行

​ 通常是聚集函数!

4.3.2 collect_set

描述:

collect_set(x) - Returns a set of objects with duplicate elements eliminated

返回一组去重后的数据组成的set集合!

4.3.3 collect_list

描述:

collect_list(x) - Returns a list of objects with duplicates

返回一组数据组成的list集合!不去重!

4.4 判断句式

4.4.1 if

​ 类似三元运算符!做单层判断!

​ 语法:

if('条件判断','为true时','为false时')

​ 示例:

select empno,ename,sal,if(sal<1500,'Poor Gay','Rich Gay') from emp;

4.4.2 case-when

​ 类似swith-case!做多层判断!

​ 语法:

case 列名
	when1 then2
	when3 then4
	when5 then6
	...
	else7
end

​ 示例:

select empno,ename,job,case job when 'CLERK' then 'a' when 'SALESMAN' then 'b' else 'c' end from emp;

4.5 列转行

1.函数说明 EXPLODE(col):将hive一列中复杂的array或者map结构拆分成多行。 LATERAL VIEW
用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias
解释:用于和split, explode等UDTF一起使用,它能够将一列数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。

4.5.1 含义

​ 列传行: 1列1行 转为 N列N行

4.5.2 explode

​ 描述:

explode(a) - separates the elements of array a into multiple rows, or the elements of a map into multiple rows and columns

​ explode使用的对象是array或map!

​ explode函数可以将一个array中的元素分割为N行1列!

select explode(friends) from default.t1 where name='songsong';

​ explode函数可以将一个 map中的元素(entry)分割为N行2列!

select explode(children) from default.t1 where name='songsong';

注意: explode函数在查询时不能写在select之外,也不能嵌套在表达式中!

​ 在select中写了explode函数,select中只能有explode函数不能有别的表达式!

4.6 LATERAL VIEW(侧写)

在Join时,由于没有关联字段,造成笛卡尔集,.hive 提供了支持此需求的实现,称为LATERAL VIEW(侧写)

炸裂的临时结果集中的每一行,可以和炸裂之前的所在行的其他字段进行join!

语法:

select 临时列名,其他字段
from 表名
-- 将 UDTF函数执行的返回的结果集临时用 临时表名代替,结果集返回的每一列,按照顺序分别以临时--列名代替
lateral view UDTF() 临时表名 as 临时列名,...

五、窗口函数

官网参考链接https://cwiki.apache.org/confluence/display/Hive/LanguageManual+WindowingAndAnalytics

​ 窗口函数=函数+窗口

​ 函数: 要运行的函数!只有以下函数称为窗口函数!

​ 开窗函数:

​ LEAD : 用来返回当前行以下行的数据!

  • LEAD (列名 [,offset] [,default])

​ offset是偏移量,默认为1,

​ default: 取不到值就使用默认值代替

LAG: 用来返回当前行以上行的数据!

  • LAG (列名 [,offset] [,default])

​ offset是偏移量,默认为1,

​ default: 取不到值就使用默认值代替

FIRST_VALUE: 返回指定列的第一个值

  • FIRST_VALUE(列名,[false是否忽略null值])

LAST_VALUE:返回指定列的最后一个值

  • LAST_VALUE(列名,[false是否忽略null值])

以上函数的操作示例https://blog.csdn.net/SunnyYoona/article/details/56484919
​ 标准的聚集函数:MAX,MIN,AVG,COUNT,SUM

​ 分析排名 函数:

  • RANK
  • ROW_NUMBER
  • DENSE_RANK
  • CUME_DIST
  • PERCENT_RANK
  • NTILE

操作示例[Hive]分析函数 RANK ROW_NUMBER CUME_DIST CUME_DIST

​ 窗口: 函数在运行时,计算的结果集的范围!

​ 窗口函数指以上特定函数在运算时,可以自定义一个窗口(计算的范围)

语法

函数 over( [partition by 字段1,字段2] [order by 字段 asc|desc] [window clause] )

​ partition by : 根据某些字段对整个数据集进行分区!

​ order by: 对分区或整个数据集中的数据按照某个字段进行排序!

​ 注意: 如果对数据集进行了分区,那么窗口的范围不能超过分区的范围!

​ 既窗口必须在区内指定!

window clause

(ROWS | RANGE) BETWEEN (UNBOUNDED | [num]) PRECEDING AND ([num] PRECEDING | CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING)
(ROWS | RANGE) BETWEEN CURRENT ROW AND (CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING)
(ROWS | RANGE) BETWEEN [num] FOLLOWING AND (UNBOUNDED | [num]) FOLLOWING

定义起始行和终止行的范围即可!

两个特殊情况:

①When both ORDER BY and WINDOW clauses are missing, the WINDOW specification defaults to ROW BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING.

当over()既没有写order by,也没有写window 子句,此时窗口默认等同于上无边界到下无边界(整个数据集)

②When ORDER BY is specified with missing WINDOW clause, the WINDOW specification defaults to RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.

当over()中,指定了order by 但是没有指定 window 子句,此时窗口默认等同于 上无边界到当前行

支持Over(),但是不支持在over中定义windows子句的函数:

The OVER clause supports the following functions, but it does not support a window with them (see HIVE-4797):

Ranking functions: Rank, NTile, DenseRank, CumeDist, PercentRank.

Lead and Lag functions

你可能感兴趣的:(Hive)