🔝Hive入门培训

Hive入门培训 – 菠萝大数据梦工厂(Free World) – 博客频道 – CSDN.NET http://blog.csdn.net/jiangshouzhuang/article/details/52129540

Hive数据类型
基础数据类型:
TINYINT,SMALLINT,INT,BIGINT,BOOLEAN,FLOAT,DOUBLE,STRING,BINARY,TIMESTAMP,DECIMAL,CHAR,VARCHAR,DATE。
复杂数据类型:
包括ARRAY(数组),MAP(字典),STRUCT(结构体),UNION(联合体),这些复杂类型是由基础类型组成的。

ARRAY:ARRAY类型是由一系列相同数据类型元素组成的,这些元素可以通过下标来访问。比如有一个ARRAY类型的变量fruits,它是由[‘apple’,’orange’,’mango’]组成,那么可以通过fruits[1]来访问orange;

MAP:MAP包含key->value键值对,可以通过key来访问元素。比如”userlist”是一个map类型(其中username是key,password是value),那么我们可以通过userlist[‘username’]来得到这个用户对应的password;

STRUCT:STRUCT可以包含不同数据类型的元素。这些元素可以通过点的方式来得到,比如user是一个STRUCT类型,那么可以通过user.address得到这个用户的地址。

UNION: UNIONTYPE

示例:
Array演示:
create table test
(
name string,
value array<string>
) row format delimited
fields terminated by ‘|’
collection itemsterminated by ‘,’;

文件:array.txt
bigdata|Spark,Hadoop
warehouse|hive,impala,Hbase

load data local inpath’/hadoop/ylxsource/myspark/testdata/array.txt’ into table test;
select name, value[0]from test;

Map演示:
create tabletest_map(name string, value map<string,int>)
row format delimited
fields terminated by ‘|’
collection itemsterminated by ‘,’
map keys terminated by’:’;

文件:map.txt
bigdata|Spark:95,Hadoop:85
warehouse|Hive:80,Impala:70,HBase:90

load data local inpath’/hadoop/ylxsource/myspark/testdata/map.txt’ into table test_map;

select name,value[“Spark”] from test_map;

Struct演示:
create tabletest_struct(id int,name struct<bigdata:string,value:int>)
row format delimited
fields terminated by ‘|’
collection itemsterminated by ‘,’;

文件:struct.txt
1|Spark,100
2|Hive,90

load data local inpath ‘/hadoop/ylxsource/myspark/testdata/struct.txt’into table test_struct;

select id, name.bigdatafrom test_struct;

Union演示:
create tabletest_union(id int,name map<string,array<string>>)
row format delimitedfields terminated by ‘|’
collection items terminatedby ‘,’
map keys terminated by’:’;

1|Spark:95,10,85
2|Hadoop:85,20,65

Hive文件格式
1. Textfile
Hive默认格式,数据不做压缩,磁盘开销大,数据解析开销大。****
可结合Gzip、Bzip2、Snappy等使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。

2. Sequencefile
Hadoop API提供的一种二进制文件支持,它将数据(key,value)的形式序列化到文件中,其具有使用方便、可分割、可压缩的特点。SequenceFile支持三种压缩选择:NONE,RECORD,BLOCK。RECORD压缩率低,一般建议使用BLOCK压缩。

3. Rcfile
RCFile是Hive推出的一种专门面向列的数据格式。 它遵循“先按列划分,再垂直划分”的设计理念。
当查询过程中,针对它并不关心的列时,它会在IO上跳过这些列。需要说明的是,RCFile在map阶段从远端拷贝仍然是拷贝整个数据块,并且拷贝到本地目录后,RCFile并不是真正直接跳过不需要的列,并跳到需要读取的列,而是通过扫描每一个row group的头部定义来实现的。
但是在整个HDFS Block 级别的头部并没有定义每个列从哪个row group起始到哪个row group结束。所以在读取所有列的情况下,RCFile的性能反而没有SequenceFile高。

4. ORC
Hive命令行常见操作
l 查看所有数据库
show databases;

l 使用数据库
use hive;

l 查看数据库信息
desc database hive;

l 查看当前使用的数据库
set hive.cli.print.current.db=true;

l 显示列头
set hive.cli.print.header=true;

l 创建数据库
create database hive;

l 删除数据库
drop database hello;
如果数据库不为空,则使用cascade关键字:
drop database IF EXISTS hello cascade;

l 查看数据库的表
show tables;
show tables like ‘test‘;
show tables in myspark;

l 获取表信息
show create table test;
desc formatted test;
desc extended test;

l 创建表

CREATE[TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS][db_name.]table_name — (Note: TEMPORARY available inHive 0.14.0 and later)
[(col_namedata_type [COMMENT col_comment], …)]
[COMMENTtable_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], …)]
[CLUSTEREDBY (col_name, col_name, …) [SORTED BY (col_name [ASC|DESC], …)] INTOnum_buckets BUCKETS]
[SKEWEDBY (col_name, col_name,…) — (Note: Available in Hive 0.10.0 and later)]
ON((col_value, col_value, …), (col_value, col_value, …), …)
[STOREDAS DIRECTORIES]
[
[ROWFORMAT row_format]
[STOREDAS file_format]
|STORED BY ‘storage.handler.class.name’ [WITH SERDEPROPERTIES (…)] — (Note: Available inHive 0.6.0 and later)
]
[LOCATIONhdfs_path]
[TBLPROPERTIES(property_name=property_value, …)] — (Note: Available inHive 0.6.0 and later)
[ASselect_statement]; — (Note: Available in Hive 0.5.0 and later; not supported for external tables)

CREATE[TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
LIKEexisting_table_or_view_name
[LOCATION hdfs_path];

data_type
:primitive_type
|array_type
|map_type
|struct_type
|union_type — (Note: Available in Hive 0.7.0 and later)

primitive_type
:TINYINT
|SMALLINT
|INT
|BIGINT
|BOOLEAN
|FLOAT
|DOUBLE
|STRING
|BINARY — (Note: Available inHive 0.8.0 and later)
|TIMESTAMP — (Note: Available in Hive 0.8.0 and later)
|DECIMAL — (Note: Available inHive 0.11.0 and later)
|DECIMAL(precision, scale) — (Note: Available inHive 0.13.0 and later)
|DATE — (Note: Available in Hive 0.12.0 and later)
|VARCHAR — (Note: Available inHive 0.12.0 and later)
|CHAR — (Note:Available in Hive 0.13.0 and later)

array_type
:ARRAY < data_type >

map_type
:MAP < primitive_type, data_type >

struct_type
:STRUCT < col_name : data_type [COMMENT col_comment], …>

union_type
:UNIONTYPE < data_type, data_type, … > — (Note: Available inHive 0.7.0 and later)

row_format
:DELIMITED [FIELDS TERMINATED BY char [ESCAPED BY char]] [COLLECTION ITEMS TERMINATED BY char]
[MAPKEYS TERMINATED BY char] [LINES TERMINATED BY char]
[NULLDEFINED AS char] — (Note: Available in Hive 0.13 and later)
|SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value,property_name=property_value, …)]

file_format:
:SEQUENCEFILE
|TEXTFILE — (Default, depending onhive.default.fileformat configuration)
|RCFILE — (Note: Available inHive 0.6.0 and later)
|ORC — (Note: Available inHive 0.11.0 and later)
|PARQUET — (Note: Available inHive 0.13.0 and later)
|AVRO — (Note:Available in Hive 0.14.0 and later)
|INPUTFORMAT input_format_classname OUTPUTFORMAToutput_format_classname

· 用户可以用 IF NOT EXIST 选项来忽略这个异常。
· EXTERNAL关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
· LIKE允许用户复制现有的表结构,但是不复制数据。
· 用户在建表的时候可以自定义 SerDe 或者使用自带的 SerDe。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的 SerDe。在建表的时候,用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的 SerDe,Hive 通过 SerDe 确定表的具体的列的数据。
· 如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCE 。
· 有分区的表可以在创建的时候使用 PARTITIONED BY 语句。一个表可以拥有一个或者多个分区,每一个分区单独存在一个目录下。而且,表和分区都可以对某个列进行 CLUSTERED BY 操作,将若干个列放入一个桶(bucket)中。也可以利用SORT BY 对数据进行排序。这样可以为特定应用提高性能。
· 表名和列名不区分大小写,SerDe 和属性名区分大小写。表和列的注释是字符串
SerDe是Serialize/Deserilize的简称,目的是用于序列化和反序列化。

l 加载数据
LOAD DATA [LOCAL] INPATH ‘filepath’ [OVERWRITE]INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 …)]

l 创建桶

《🔝Hive入门培训》

create table par_table
(
id int,
type string,
value string
)
partitioned by(data_date string, posstring)
clustered by(id) sorted by(value)into 32 buckets
row format delimited
fields terminated by ‘|’
lines terminated by ‘\n’
stored as sequencefile;

强制分桶

set hive.enforce.bucketing = true;

对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive也是针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。

把表(或者分区)组织成桶(Bucket)有两个理由:

  1.  获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接(Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
    
  2.  使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
    

对于Map端连接的情况,两个表以相同方式划分桶。处理左边表内某个桶的 mapper知道右边表内相匹配的行在对应的桶内。因此,mapper只需要获取那个桶 (这只是右边表内存储数据的一小部分)即可进行连接。这一优化方法并不一定要求两个表必须桶的个数相同,两个表的桶个数是倍数关系也可以。

l Hive Client数据操作
hive -help
hive –help

hive -e “use hive;select * from words”
hive -S -e “use hive;select * from words”

hive -f hivecli.sql
hive -S -f hivecli.sql
hive (hive)> source /hadoop/ylxsource/myspark/testdata/hivecli.sql;

hive -S -f hivecli.sql > result.txt

hive (hive)> set val=bigdata;
select * from test where name = ‘${hiveconf:val}’;

通过sh脚本执行:
test.sh
#!/bin/bash
hive-S -e “
usehive;
select from test;”*

bash test.sh

Hive数据加载(内部表,外部表,分区表)
内部表数据加载

  1.  创建表时加载数据
    

create table test_bak as select * from test;

  1.  创建表时指定数据路径
    

create table if not exists test2(
id int,
name string,
score int
)
row format delimited fields terminated by’|’
lines terminated by ‘\n’
stored as textfile
location’file:/hadoop/ylxsource/myspark/testdata/location’;
表删除时,数据目录也会删除

  1.  本地数据加载
    

create table if not exists test2(
id int,
name string,
score int
)
row format delimited fieldsterminated by ‘|’
lines terminated by ‘\n’
stored as textfile;

load data local inpath’/hadoop/ylxsource/myspark/testdata/external.txt’ into table test2;

  1.  HDFS数据加载
    

create table if not exists test2(
id int,
name string,
score int
)
row format delimited fieldsterminated by ‘|’
lines terminated by ‘\n’
stored as textfile;

load data inpath’hdfs://SZB-L0007971:28888/testdata/external.txt’ into table test2;
load data inpath’hdfs://SZB-L0007971:28888/testdata/external.txt’ overwrite into table test2;

  1.  通过hdfs命令将数据拷贝到指定的表的目录下面
    

hdfs dfs -put external.txthdfs://SZB-L0007971:28888/user/hive/myspark/hive.db/test2/external2.txt
此种方式和内部表相同。

  1.  由查询语句加载数据
    

insert overwrite table test2 select * from test3;
insert into table test2 select * from test3;

外部数据加载

  1.  创建外部表时指定分区
    

create external tableif not exists test2(
id int,
name string,
score int
)
row formatdelimited fields terminated by ‘|’
lines terminatedby ‘\n’
stored astextfile
location’hdfs://SZB-L0007971:28888/testdata/external/’;

load data inpath ‘hdfs://SZB-L0007971:28888/testdata/external’into table test2 partition(dt=20160115);

show partitions test2;

  1.  查询时插入数据
    

drop table IF EXISTShdp_circ_annuity_number_60s;
create table IF NOT EXISTShdp_circ_annuity_number_60s
(
polno stringcomment ‘保单号’,
plan_code stringcomment ‘险种代码’,
deptno stringcomment ‘部门’,
p_number decimal(18) comment ‘人数’
)
partitioned by (flag string, data_date string)
row format delimited fields terminated by ‘\001’ ;

insert overwrite tablehdp_circ_annuity_number_60s partition(flag, data_date)
select polno,
plan_code,
deptno,
count(distinct insno) as p_number,
‘A1’ as flag,
‘20160101’ as data_date
from hdp_gbs_pol_ben_tmp
where to_date(undwrt_date) >= ‘2015-12-01’ and to_date(undwrt_date)< ‘2016-01-01’
group by polno,
plan_code,
deptno

  1.  加载数据到分区表
    

load data local inpath ‘/home/hadoop/data.txt’ overwriteinto table test partition (ds=’2013-08-16′);

load data inpath ‘hdfs://SZB-L0007971:28888/hadoop’overwrite into table test partition (ds=’2013-08-16′);

Hive数据加载注意问题
分隔符问题:
分隔符默认只有单个字符。如果有多个字符,默认取第一个字符作为分隔符。
数据类型对应问题: load数据数据,字段类型不能互相转化时,查询结果返回NULL。而实际的数据仍然存在。
select查询插入,字段类型不能互相转化时,插入数据为NULL。而实际的数据也为NULL。
其他:
select查询插入数据,字段值顺序要与表中字段顺序一致,名称可不一致。 Hive在数据加载时不做检查,查询时检查
外部分区表需要添加分区才能看到数据。

Hive数据导出
使用HDFS命令导出
desc formatted test;获取location路径
使用get方式获取:
hdfs dfs -get hdfs://SZB-L0007971:28888/user/hive/myspark/hive.db/test/array.txtresult.txt
使用text方式获取:
hdfs dfs –texthdfs://SZB-L0007971:28888/user/hive/myspark/hive.db/test/array.txt > ok
通过INSERT … DIRECTORY方式
insert overwrite local directory’/hadoop/ylxsource/myspark/testdata/test2′
row format delimited fields terminated by’\t’
select * from test2;

insert overwrite directory’hdfs://SZB-L0007971:28888/testdata/test2′
row format delimited fields terminated by ‘\t’
select * from test2;

Shell命令方式
hive -S -e “use hive; select * fromtest2;” > result.txt

第三方工具Sqoop
sqoop import/export

Hive动态分区
动态分区指不需要为不同的分区添加不同的插入语句,分区不确定,需要从数据中自动获取。

相关参数配置

开启动态分区

set hive.exec.dynamic.partition=true;

如果模式是strict,则必须有一个静态分区,且放在最前面

set hive.exec.dynamic.partition.mode=nonstrict;

每个节点生成动态分区最大个数

sethive.exec.max.dynamic.partitions.pernode=10000;

生成动态分区最大个数,如果自动分区数大于这个参数,将会报错

set hive.exec.max.dynamic.partitions=100000;

一个任务最多可以创建的文件数目

set hive.exec.max.created.files=150000;

限定一次最多打开的文件数

set dfs.datanode.max.xcievers=8192;

create table dynamic_table(
id int
)
partitioned by (name string,score string)
row format delimited
fields terminated by ‘\t’
lines terminated by ‘\n’
stored as textfile;

insert overwrite table dynamic_tablepartition(name,score)
select id,name,score from test2;

show partitions dynamic_table;

如果参数set hive.exec.dynamic.partition.mode=strict,则必须指定一个静态分区字段:
sethive.exec.dynamic.partition.mode=strict;
再执行上面的语句:
insert overwrite table dynamic_tablepartition(name,score)
select id,name,score from test2;
会报如下错误:
FAILED: SemanticException [Error 10096]: Dynamic partition strict mode requires at least one staticpartition column. To turn this off sethive.exec.dynamic.partition.mode=nonstrict

需要如下方式指定一个静态分区字段:
insert overwrite table dynamic_tablepartition(name=’Bigdata’,score)
select id,score from test2;

Hive表字段属性修改
l 修改表名
alter table test2 rename to new_test2;

l 添加字段
alter table new_test2 add columns(count1 intcomment ‘count1’, count2 int comment ‘count2’);

l 修改字段
create tabletest_change (a int, b int, c int);

alter tabletest_change change a a1 int;

alter tabletest_change change a1 a2 string after b;

alter tabletest_change change c c1 int first;

l 修改表属性
alter table new_test2 set tblproperties(‘comment’= ‘this is the table new_test2’);

l 外部表和内部表互转
内部表转外部表:
altertable new_test2 set TBLPROPERTIES (‘EXTERNAL’ = ‘TRUE’);

外部表转内部表:
altertable new_test2 set TBLPROPERTIES(‘EXTERNAL’=’FALSE’);

Hive常见内置函数及其使用
l 查看当前可用函数等信息
show functions;

显示函数的描述信息
DESC FUNCTION concat;

显示函数的扩展描述信息
DESC FUNCTION EXTENDED concat;

l 简单函数
函数的计算粒度为单条记录。
关系运算
数学运算
逻辑运算
数值计算
类型转换
日期函数
条件函数
字符串函数
统计函数

l 聚合函数
函数处理的数据粒度为多条记录。
sum()—求和
count()—求数据量
avg()—求平均直
distinct—求不同值数
min—求最小值
max—求最人值

l 集合函数
复合类型构建
复杂类型访问
复杂类型长度

l 特殊函数

  1. 窗口函数
    应用场景:
    用于分区排序
    动态Group By
    Top N
    累计计算
    层次查询

函数:
lead
lag
last_day
last_value

  1. 分析函数
    RANK
    ROW_NUMBER
    DENSE_RANK
    CUME_DIST
    PERCENT_RANK
    NTILE
  1. 混合函数
    java_method(class,method [,arg1 [,arg2])
    reflect(class,method [,arg1 [,arg2..]])
    hash(a1 [,a2…])

  2. UDTF
    lateralView: LATERAL VIEW udtf(expression)tableAlias AS columnAlias (‘,’ columnAlias)*
    fromClause: FROM baseTable (lateralView)*

例如:
select t.word_list,count(1) from
(
select word_list from words w lateral view explode(split(w.word,’ ‘)) ww as word_list
) t group by t.word_list;

lateral view用于和split,explode等UDTF一起使用,它能够将一行数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。lateral view首先为原始表的每行调用UDTF,UTDF会把一行拆分成一或者多行,lateral view再把结果组合,产生一个支持别名表的虚拟表。

l 常用函数

  1. 获取当前时间
    selectfrom_unixtime(unix_timestamp(),’yyyy-MM-dd HH:mm:ss’);

  2. 截取时间
    selectregexp_replace(substr(‘2016-01-18′,0,7),’-‘,”);
    select to_date(‘2016-01-18 12:24:12’);

  3. 修改日期格式
    select from_unixtime(to_unix_timestamp(‘2014/6/18′,’yyyy/MM/dd’),’yyyy-MM-ddHH:mm:ss’);

  4. 数据类型强制转换
    select cast(‘1314’ as int);

  5. 判断语句
    select ossdkversion,
    osversion,
    mobilemodel,
    carrier,
    networkconntype,
    org_name,
    e_version,
    channel,
    data_date,
    ‘登录’ as module,
    case tmp.lable
    when ‘用户登陆’ then ‘用户名+密码登录次数’
    when ‘手势登录成功’ then ‘手势密码登录成功次数’
    when ‘手势设置失败’then ‘手势密码设置失败次数’
    when ‘手势登录失败’ then ‘手势密码登录失败次数’
    when ‘忘记密码’ then ‘忘记密码’
    end flag
    frome_temp tmp
    wheretmp.lable in (‘用户登陆’,’手势登录成功’,’手势设置失败’,’手势登录失败’,’忘记密码’)

select if(‘o’=’o’,’o_o’,’o‘);

   6. 解析Json格式内容
   selectget_json_object('{"name":"spark","age":"10"}','$.name');

   7. 解析URL地址
   SELECTparse_url('http://facebook.com/path/p1.[PHP](http://lib.csdn.net/base/php)?query=1', 'HOST');
   SELECTparse_url('http://facebook.com/path/p1.php?query=1', 'QUERY')
   SELECT parse_url('http://facebook.com/path/p1.php?query=1','QUERY', 'query');
  
   8. 字符串连接函数
   select concat('S','p','a','r','k');

select concat_ws(‘-‘,’S’,’p’,’a’,’r’,’k’);

  1. 输出数组集合
    列出该字段所有不重复的值,相当于去重
    collect_set(polno) //返回的是数组

列出该字段所有的值,列出来不去重
collect_list(polno) //返回的是数组

select collect_set(polno) frommyspark.pol_ben_s;
select collect_list(polno) frommyspark.pol_ben_s;

  1. 窗口函数:
    first_value:
    select polno,certno,first_value(certno) over (partition bypolno order by certno desc ) from myspark.pol_ben_s;
    rank:
    select polno,certno, rank() over (partition by polno order bycertno) as rank from myspark.pol_ben_s;
    row_number:
    select polno,certno, row_number() over (partition by polnoorder by certno) as rank from myspark.pol_ben_s;

row_number()是没有重复值的排序(即使两天记录相等也是不重复的),可以利用它来实现分页
dense_rank()是连续排序,两个第二名仍然跟着第三名
rank()是跳跃拍学,两个第二名下来就是第四名

  1. 使用正则表达式
    selectregexp_extract(‘x=a3&x=18abc&x=2&y=3&x=4′,’x=([0-9]+)([a-z]+)’,0);
    selectregexp_extract(‘x=a3&x=18abc&x=2&y=3&x=4′,’x=([0-9]+)([a-z]+)’,1);
    selectregexp_extract(‘x=a3&x=18abc&x=2&y=3&x=4′,’x=([0-9]+)([a-z]+)’,2);
    原文作者:葡萄喃喃呓语
    原文地址: https://www.jianshu.com/p/65db42f1831c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞