Hive学习笔记(五)

转载请标明出处:
http://blog.csdn.net/zwto1/article/details/48850583;
本文出自:【明月的博客】

前言

本文主要涉及hive的相关操作DML。

hive操作

导入数据:

load data :把文件复制或移到表的目录中,从而把数据导入hive的表或分区。
insert:把数据从一个hive表填充到另一个。
ctas:create table … as select 的缩写。
sqoop:把关系型数据库直接导入hive.

insert语句:

insert overwrite table target select col1,col2 from source;

分区的表使用partition子句来指明数据要插入哪个分区:

insert overwrite table target partition(dt='20150826') select col1,col2 from source;

OVERWRITE关键字:目标表的内容会被select语句的结果替换掉。
select 语句可以使用分区值来动态指明分区:

insert overwrite table target partition(dt) select col1,col2,dt from source;

这个特性默认是关闭的,使用前把

hive.exec.dynamic.partition  设为true.

多表插入:

HiveQL 可以把from子句放在最前面,查询效果一样。

from source
insert overwrite table target select col1,col2;

可以在一个查询中使用多个insert子句,这样的效率比多个单独的insert语句效率更高,因为只需要扫一遍源表就可以生成多个输出。
eg: 根据气象数据集来计算多种不同的统计数据:

from records
insert overwrite table stations_by_year select year,count(distinct station) group by year insert overwrite table records_by_year select year,count(distinct station) group by year insert overwrite table good_records_by_year select year,count(1) where temperature != 9999 and(quatity=0 or quatity=0 or quatity=0 or quatity=0 or quatity=0 ) group by year;

一个源表records,有三个表用于存放针对源表的三个不同查询结果。

create table as select :

把hive查询的输出结果存放到一个新的表
新表列的定义是从select 子句所检索出来的列导出的。
eg:

create table target as select col1,col2 from source;

目标表有两列,分别为col1,col2,它们的数据类型和源表相同。
CTAS操作是原子,select 查询失败,不会创建新表。

表的修改:

hive支持对表定义的修改
eg:alter table重命名表:

alter table source rename to target;

更新表的元数据,还把表目录移到新名称对应的目录下。外部表只更新元数据,不会移动目录。
hive 允许修改列的定义,添加新的列,甚至用新的列替换表内已有的列。
eg:
添加新列:

alter table target add columns (col3 String);

新添加的列在在已有(非分区)列的后面,数据文件没有更新,要进行底层文件的更新,常用做法是创建一个新定义的列的表,使用select 语句把数据填充进去。

表的丢弃:

DROP TABLE 语句用于删除元数据,如果是外部表,只删除元数据。
要删除表内所有数据但要保留表的定义(如mysql的delete或truncate),删除数据文件即可。
eg:

dfs -rmr   /user/hive/warehouse/mytable

补充:mysql delete与truncate 的区别?
hive把缺少文件或者根本没有表对应的目录的表,认为是空表。达到类似目的的方法是使用like关键字创建一个与第一个模式相同的新表。

create table new_table like existing_table;

查询数据:

排序和聚集
order by 能产生完全排序的结果,但它通过一个reduce来做到这一点,对大规模的数据集,效率比较低。
很多情况不需全局排序,可以使用sort by 。sort by 为每个reduce产生一个排序文件。
通常为了后续的聚集操作,需要控制特定的行到哪个reduce,这就是hive的distribute by 子句做的事情。
eg:根据年份和气温对气象数据集进行排序,确保具有相同年份的行,最终都在同一个reduce分区中:

from records2
select year ,temperature distribute by year sort by year asc,temperature desc;

同一个年份的气温已经在同一个文件中分好组并且以降序排好序。
如果sort by 与 distribute by中所用的列相同,可以缩写为cluster by 以便同时指定两者所用的列。

MapReduce脚本:

使用hadoop streaming、TRANSFORM 、MAP、REDUCE子句这样的方法,便可以在hive中调用外部脚本。
eg:用一个脚本来过滤不符合某个条件的行(删除低质量的气温读数)。

#!/usr/bin/env python
import re
import sys
for line in sys.stdin:
(year,temp,q) = line.strip().split()
if(temp!="9999" and re.match("[01459]",q)):
print"%s\t%s" %(year,temp)

如何在hive里使用这个脚本:

add file  /path/to/is_good_quality.py;
from records
select transform(year,temperature,quality) using 'is_good_quality.py' as year,temperature;

运行查询之前,需要在hive中注册脚本,运行这一操作,hive需要把脚本文件传输到hadoop集群。
查询本身把year,te mperature,quality这些字段以制表符的形式流式传递给脚本 is_good_quality.py,并把制表符分隔的输出解析为year和temperature字段,最终形成查询的输出。示例不使用reducer.
查询的嵌套形式,可以指定map和reduce函数,要使用map 和 reduce 两个关键字。 两个地方使用select transform 也能到达同样效果。

from (
from records2
MAP  year,temperature,quality
using  'is_good_quality.py'
as year ,temperature)map_output
REDUCE year,temperature
using 'max_temperature_reduce.py' as year,temperature;

小结

本篇主要对hive的操作做相关总结,包括数据的导入方式load data、insert into 、sqoop等,表的修改、丢弃和hive里 外部mapreduce的使用。

你可能感兴趣的:(Hive学习笔记(五))