[老实李]HIVE学习笔记

一、HIVE简介

Hive是一种建立在Hadoop文件系统上的数据仓库架构,并对存储在HDFS中的数据进行分析和管理;它可以将结构化的数据文件映射为一张数据库表,并提供完整的 SQL 查询功能,可以将 SQL 语句转换为 MapReduce 任务进行运行,通过自己的 SQL 去 查询分析需要的内容,这套 SQL 简称 Hive SQL(HQL),使不熟悉 MapReduce 的用户也能很方便地利用 SQL 语言对数据进行查询、汇总、分析。同时,这个语言也允许熟悉 MapReduce 开发者们开发自定义的mappers和reducers来处理内建的mappers和reducers无法完成的复杂的分析工作。Hive还允许用户编写自己定义的函数UDF,用来在查询中使用。Hive中有3种UDF:User Defined Functions(UDF)、User Defined Aggregation Functions(UDAF)、User Defined Table Generating Functions(UDTF)。也就是说对存储在HDFS中的数据进行分析和管理,我们不想使用手工,我们建立一个工具吧,那么这个工具就可以是hive。

二、简单的命令

//展示方法名列表
show functions;
//简单方法的解释
desc function split;

image.png

//解释方法名并且举个例子
desc function extended split;

image.png

//查找sp开头的方法名
show functions like 'sp.*';

image.png

三、分区和分桶

1.分区

(1)什么是分区?
分区其实就是再HDFS上存储的时候分了一个相应的分区文件夹,比如你的一个表 partition_test,然后根据日期分区的话,最后HDFS上的就是类似这样的结构
/user/hive/warehouse/partition_test/stat_date=2015-01-18/province=beijing----显示刚刚创建的分区

(2)内部表和外部表有什么区别?
1.内部表删除的时候会将表的数据和元数据信息全部删除,而外部表仅仅删除外部表的元数据,数据是不会删除的。

  1. 内部表在load data的时候会将数据转移。也就是说 load data inpath '/input/edata' into table et; 这句话会把HDFS上的/input/edata文件移动到表et的location下面。而外部表不会。
    3.内部表和外部表都会在 /user/hive/warehouse/新建一个表的目录(如果不指定location的话)

(3)内部分区表和外部分区表
创建一个简单的内部分区表

create table partition_internal(

id INT COMMENT 'student id',

name  STRING COMMENT 'student name',

age INT COMMENT 'student age')

PARTITIONED BY(province STRING,city STRING)

ROW FORMAT DELIMITED

FIELDS TERMINATED BY '\t';

//为内部分区表指定分区
ALTER TABLE partition_internal ADD PARTITION (province='henan',city='zhengzhou');
//加载数据到内部分区表 这个时候会移动数据
LOAD DATA INPATH '/user/hive/external01' INTO TABLE partition_internal PARTITION(province='henan',city='zhengzhou');
创建外部分区表

create  external table partition_external(

id INT COMMENT 'student id',

name  STRING COMMENT 'student name',

age INT COMMENT 'student age')

PARTITIONED BY(province STRING,city STRING)

ROW FORMAT DELIMITED

FIELDS TERMINATED BY '\t';
create  external table partition_external(

id INT COMMENT 'student id',

name  STRING COMMENT 'student name',

age INT COMMENT 'student age')

ROW FORMAT DELIMITED

FIELDS TERMINATED BY '\t'

LOCATION '/user/hive/external02';

为外部分区表添加分区
ALTER TABLE partition_external ADD PARTITION (province='shanxi',city='xian') LOCATION '/user/hive/external02';

//查看分区
show partitions partition_external;

//删除分区
ALTER TABLE student_partition_external DROP PARTITION(province='guangzhou',city='shenzhen');

//向多个分区插入数据,命令如下。
from partition_test_input

insert overwrite table partition_test partition(stat_date='2015-01-18',province='jiangsu') select member_id,name from partition_test_input where stat_date='2015-01-18' and province='jiangsu'

insert overwrite table partition_test partition(stat_date='2015-01-28',province='sichuan') select member_id,name from partition_test_input where stat_date='2015-01-28' and province='sichuan'

insert overwrite table partition_test partition(stat_date='2015-01-28',province='beijing') select member_id,name from partition_test_input where stat_date='2015-01-28' and province='beijing';

(4)动态分区
按照上面的方法向分区表中插入数据,如果数据源很大,针对一个分区就要写一个 insert ,非常麻烦。使用动态分区可以很好地解决上述问题。动态分区可以根据查询得到的数据自动匹配到相应的分区中去。

1、启动动态分区功能(默认没有启动)
set hive.exec.dynamic.partition = true;

2、设置所有分区都是动态的
set hive.exec.dynamic.partition.mode=nostrict;

3、准备两个表:一个普通外部表student_external01,一个分区外部表student02
而且要保证分区表结构student02和student_external01一致
我们以student_external01表为例,但是少两个分区字段,所以我们再增加两个字段。
ALTER TABLE student_external01 ADD COLUMNS(province STRING,city STRING);

4、先往外部表student_external01中加载数据(实际上现在外部表student_external01中已经有数据了,因为创建该表时指定了location)
LOAD DATA INPATH '/user/hive/external02/student.txt' INTO TABLE student_external01;

5、利用动态分区向表中插入数据
//先创建分区外部表student02

create  external table student02(

id INT COMMENT 'student id',

name  STRING COMMENT 'student name',

age INT COMMENT 'student age')

PARTITIONED BY(province STRING,city STRING)

ROW FORMAT DELIMITED

FIELDS TERMINATED BY '\t';

//利用动态分区向表中插入数据
INSERT OVERWRITE TABLE student02 PARTITION(province,city) SELECT * FROM student_external01 ;
然后数据就会动态分区,把对应的数据放到对应的分区下。

image.png

2.桶操作

Hive 中 table 可以拆分成 Partition table 和 桶(BUCKET),分区提供了一个隔离数据和优化查询的便利方式,不过并非所有的数据都可形成合理的分区,尤其是需要确定合适大小的分区划分方式,(不合理的数据分区划分方式可能导致有的分区数据过多,而某些分区没有什么数据的尴尬情况)分桶是将数据集分解为更容易管理的若干部分的另一种技术。

数据分桶的原理: 跟MR中的HashPartitioner的原理一模一样, 按照分桶字段的hash值去模除以分桶的个数

和分区的区别:分桶中的字段是原始数据中存在的,而分区字段在原始文件中并不存在。比如我们上面的那个分区province和city字段就是不在student02中的(如果指定了分区并且表的字段中还包含这两个字段的话,hive会报错的)

1、开启分桶功能

set hive.enforce.bucketing=true;

2、创建桶表

CREATE TABLE IF NOT EXISTS bucket_table(

id INT COMMENT 'student id',

name  STRING COMMENT 'student name',

age INT COMMENT 'student age')

CLUSTERED BY(id) INTO 3 BUCKETS

ROW FORMAT DELIMITED

FIELDS TERMINATED BY '\t';

3、插入数据到桶表中
INSERT OVERWRITE TABLE bucket_table SELECT id,name,age FROM student_external01;

二.HIVE复合类型

hive提供了复合数据类型:

1.Structs: structs内部的数据可以通过DOT(.)来存取。例如,表中一列c的类型为STRUCT{a INT; b INT},我们可以通过c.a来访问域a。

  1. 建表
hive> create table student_test(id INT, info struct< name:STRING, age:INT>)

> ROW FORMAT DELIMITED FIELDS TERMINATED BY ','

> COLLECTION ITEMS TERMINATED BY ':';

'FIELDS TERMINATED BY' :字段与字段之间的分隔符。'COLLECTION ITEMS TERMINATED BY' :一个字段各个item的分隔符。

  1. 导入数据(注意最后不要带空格不然识别就是NULL)
$ cat test5.txt

1,zhou:30

2,yan:30

3,chen:20

4,li:80

hive> LOAD DATA LOCAL INPATH '/home/hadoop/djt/test5.txt' INTO TABLE student_test;

  1. 查询数据

hive> select info.age from student_test;

2.Map(K-V对):访问指定域可以通过["指定域名称"]进行。例如,一个Map M包含了一个group-》gid的kv对,gid的值可以通过M['group']来获取。

  1. 建表
hive> create table employee(id string, perf map< string, int>)

 ROW FORMAT DELIMITED

 FIELDS TERMINATED BY '\t'

COLLECTION ITEMS TERMINATED BY ','

MAP KEYS TERMINATED BY ':';

‘MAP KEYS TERMINATED BY’ :key value分隔符
  1. 导入数据
$ cat test7.txt

1 job:80,team:60,person:70

2 job:60,team:80

3 job:90,team:70,person:100

hive> LOAD DATA LOCAL INPATH '/home/work/data/test7.txt' INTO TABLE employee;

  1. 查询

hive> select perf['person'] from employee;

3)Array:array中的数据为相同类型。例如,假如array A中元素['a','b','c'],则A[1]的值为'b'

3.Array使用

  1. 建表
hive> create table class_test(name string, student_id_list array< INT>)

ROW FORMAT DELIMITED

FIELDS TERMINATED BY ','

COLLECTION ITEMS TERMINATED BY ':';
  1. 导入数据
$ cat test6.txt

034,1:2:3:4

035,5:6

036,7:8:9:10

hive> LOAD DATA LOCAL INPATH '/home/work/data/test6.txt' INTO TABLE class_test ;

  1. 查询

hive> select student_id_list[3] from class_test;

三、HIVE的join用法

https://blog.csdn.net/shenxiaoming77/article/details/49489713

四、HIVE的数据删除

1.删除指定行

image.png

insert overwrite table A select id,name from A where id !=2;

2.删除表中所有数据
truncate table table_name;

五、HIVE数据分析结果的保存

https://blog.csdn.net/u010159842/article/details/70193687

六、hive中order by,sort by, distribute by, cluster by作用以及用法

orderby 就一个reduce, sortby是指定几个reduce就是几个reduce进行排序,但是并不能保证所有的数据都是有序的

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的名字


image.png

执行hive语句:
select mid, money, name from store distribute by mid sort by mid asc, money asc
我们所有的mid相同的数据会被送到同一个reducer去处理,这就是因为指定了distribute by mid,这样的话就可以统计出每个商户中各个商店盈利的排序了(这个肯定是全局有序的,因为相同的商户会放到同一个reducer去处理)。这里需要注意的是distribute by必须要写在sort by之前。

4. cluster by

cluster by的功能就是distribute by和sort by相结合,如下2个语句是等价的:
select mid, money, name from store cluster by mid
select mid, money, name from store distribute by mid sort by mid
如果需要获得与3中语句一样的效果:
select mid, money, name from store cluster by mid sort by money
注意被cluster by指定的列只能是降序,不能指定asc和desc。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容