您的位置:首页 > 其它

hive的基本操作

2017-03-24 10:24 337 查看
1、创建表:

hive>create table pokes(foo int,bar string);

hive>create table new_tb like pokes; 创建一个一样的表结构

2、创建分区表:

Hive>create table logs(ts bigint,line string) partitioned by (dt string,country string);

3、加载分区表数据:

hive> load data local inpath '/home/hadoop/input/hive/partitions/file1' into table logs partition (dt='2001-01-01',country='GB');

4、展示表中有多少分区:

Hive>show partitions logs;

5、展示所有表:

Hive>show tables;

Hive>show tables ‘.*s’;

6、显示表的结构信息:

Hive>describe invites;

7、更改表的名字:

Hive>alter table source rename to terget;

8、添加新一列:

Hive>alter table invites add columns(new_col2 int comment ‘a comment’);

9、删除表:

Hive>drop table records;

删除表中数据,但要保持表的结构定义:

Hive>dfs -rmr /usr/hive/warehouse/records;

10、从本地文件加载数据:

hive> load data local inpath '/home/hadoop/input/ncdc/micro-tab/sample.txt' overwrite into table records;

11、显示所有函数

Hive>show functions;

12、查看函数用法

Hive>describe function substr;

13、查看数组,map,结构

Hive> select col1[0],col2[‘b’],col3.c from complex;

14、内连接

Hive>select sale.*,thing.* from sale join thing on (sale.id=thing.id);

15、查看hive为某个查询使用多少个mapreduce作业

Hive>explain select sale.*,thing.* from sale join thing on (sale.id=thing.id);

16、外连接

Hive> select sale.*,thing.* from sale left outer join thing on (sale.id=thing.id);

Hive> select sale.*,thing.* from sale right outer join thing on (sale.id=thing.id);

Hive> select sale.*,thing.* from sale full outer join thing on (sale.id=thing.id);

17、in查询:hive不支持,但是可以使用left semi join

Hive>select * from thing left semi join sale on(sale.id=thing.id);

18、map连接:hive可以把较小的表放在每个mapper的内存来执行连接操作

Hive>select /*+mapjoin(thing)*/ sale.*,thing.* from sale join thing on (sale.id=thing.id);

19、insert overwrite table … select :新表预先存在

Hive>from record2

>insert overwrite table stations_by_year select year,count(distinct station) group by year

> insert overwrite table records_by_year select year,count(1) group by year

> insert overwrite table good_records_by_year select year,count(1) where temperature!=999 and (quality=0 or quality=1 or quality=4) group by year;

20、create table … as select :新表预先不存在

Hive>create table target as select sol1,col2 from source;

21、创建视图

Hive>create view valid_records as select * from records2 where temperature!=999;

22、查看试图详细信息

Hive>describe extended valid_records;

Create Table语句的一些注意项:

(1)CREATE TABLE创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用IF NOT EXIST选项来忽略这个异常。

(2)EXTERNAL 关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径( LOCATION ),Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。

(3)LIKE允许用户复制现有的表结构,但是不复制数据。

(4)用户在建表的时候可以自定义SerDe或者使用自带的 SerDe ( Serialize/Deserilize 的简称,目的是用于序列化和反序列化 )。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的SerDe。在建表的时候,用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的SerDe,Hive通过SerDe确定表的具体的列的数据。

(5)如果文件数据是纯文本,可以使用STORED AS TEXTFILE。如果数据需要压缩,使用STORED AS SEQUENCE。

(6)有分区的表可以在创建的时候使用 PARTITIONED B Y语句。一个表可以拥有一个或者多个分区,每一个分区单独存在一个目录下。而且,表和分区都可以对某个列进行CLUSTERED BY操作,将若干个列放入一个桶(bucket)中。也可以利用SORT BY对数据进行排序。这样可以为特定应用提高性能。

(7)表名和列名不区分大小写,SerDe和属性名区分大小写。表和列的注释是字符串。

Alter Table语句:主要功能包括Add Partitions, Drop Partitions, Rename
Table, Change Column, Add/Replace Columns。

Create View语句:创建视图。格式CREATE VIEW [IF NOT EXISTS] view_name [
(column_name [COMMENT column_comment], ...) ]

Show语句:Show tables; Show partitions;
describe查看表结构。

Load语句:HIVE装载数据时没有做任何转换,加载到表中的数据只是进入相应的配置单元表的位置。Load操作只是单纯的复制/移动操作,将数据文件移动到Hive表对应的位置。

Insert语句:插入数据。Hive不支持一条一条的用 insert 语句进行插入操作,这个应该是与hive的storage layer是有关系的,因为它的存储层是HDFS,插入一个数据要全表扫描,还不如用整个表的替换来的快些。Hive也不支持update的操作。数据是以load的方式,加载到建立好的表中。数据一旦导入,则不可修改。要么drop掉整个表,要么建立新的表,导入新的数据。

Drop语句:删除一个内部表的同时会同时删除表的元数据和数据。删除一个外部表,只删除元数据而保留数据。

Limit子句:可以限制查询的记录数。查询的结果是随机选择的。下面的查询语句从 t1 表中随机查询5条记录,SELECT * FROM t1 LIMIT 5。

Top K查询:下面的查询语句查询销售记录最大的 5 个销售代表。

SET mapred.reduce.tasks = 1

SELECT * FROM sales SORT BY amount
DESC LIMIT 5

正则表达式使用:SELECT语句可以使用正则表达式做列选择,下面的语句查询除了ds和h 之外的所有列:

SELECT `(ds|hr)?+.+` FROM sales

SELECT语句:查询数据。

Group by, Order by, Sort
by
子句:聚合可进一步分为多个表,甚至发送到 Hadoop 的 DFS 的文件(可以进行操作,然后使用HDFS的utilitites)。可以用hive.map.aggr控制怎么进行汇总。默认为为true,配置单元会做的第一级聚合直接在MAP上的任务。这通常提供更好的效率,但可能需要更多的内存来运行成功。

Join语句:连接操作。一些注意事项:

(1)Hive只支持等值连接(equality joins)、外连接(outer joins)和(left/right joins)。Hive不支持所有非等值的连接,因为非等值连接非常难转化到map/reduce任务。

(2)Hive 支持多于2个表的连接。

(3)join 时,每次 map/reduce 任务的逻辑: reducer 会缓存 join 序列中除了最后一个表的所有表的记录, 再通过最后一个表将结果序列化到文件系统。这一实现有助于在reduce端减少内存的使用量。实践中,应该把最大的那个表写在最后(否则会因为缓存浪费大量内存)。

(4)LEFT,RIGHT 和 FULL OUTER 关键字用于处理 join 中空记录的情况。

(5)LEFT SEMI JOIN 是 IN/EXISTS 子查询的一种更高效的实现。Hive 当前没有实现 IN/EXISTS 子查询,所以你可以用 LEFT SEMI JOIN 重写你的子查询语句。LEFT SEMI JOIN的限制是, JOIN子句中右边的表只能在ON子句中设置过滤条件,在WHERE子句、SELECT子句或其他地方过滤都不行。

使用HIVE注意点 (1)字符集

Hadoop和Hive都是用UTF-8编码的,所以, 所有中文必须是UTF-8编码, 才能正常使用。

备注:中文数据load到表里面,,如果字符集不同,很有可能全是乱码需要做转码的,但是hive本身没有函数来做这个。

(2)压缩

hive.exec.compress.output 这个参数,默认是false,但是很多时候貌似要单独显式设置一遍,否则会对结果做压缩的,如果你的这个文件后面还要在hadoop下直接操作,那么就不能压缩了。

(3)count(distinct)

当前的Hive不支持在一条查询语句中有多Distinct如果要在Hive查询语句中实现多Distinct,需要使用至少n+1条查询语句(n为distinct的数目),前n条查询分别对n个列去重,最后一条查询语句对n个去重之后的列做Join操作,得到最终结果。

(4)JOIN

只支持等值连接

(5)DML操作

只支持INSERT/LOAD操作,无UPDATE和DELTE

(6)HAVING

不支持HAVING操作。如果需要这个功能要嵌套一个子查询用where限制

(7)子查询

Hive不支持where子句中的子查询 (8)Join中处理null值的语义区别

SQL标准中,任何对null的操作(数值比较,字符串操作等)结果都为null。Hive对null值处理的逻辑和标准基本一致,除了Join时的特殊逻辑。这里的特殊逻辑指的是,Hive的Join中,作为Join key的字段比较,null=null是有意义的,且返回值为true

(9)分号字符

分号是SQL语句结束标记,在HiveQL中也是,但是在HiveQL中,对分号的识别没有那么智慧,例如:

select concat(cookie_id,concat(';',’zoo’)) from c02_clickstat_fatdt1 limit 2;

FAILED: Parse Error: line 0:-1 cannot recognize input '<EOF>' in function
specification

可以推断,Hive解析语句的时候,只要遇到分号就认为语句结束,而无论是否用引号包含起来。

解决的办法是,使用分号的八进制的ASCII码进行转义,那么上述语句应写成:

select concat(cookie_id,concat('\073','zoo')) from c02_clickstat_fatdt1 limit
2;

为什么是八进制ASCII码?我尝试用十六进制的ASCII码,但Hive会将其视为字符串处理并未转义,好像仅支持八进制,原因不详。这个规则也适用于其他非SELECT语句,如CREATE TABLE中需要定义分隔符,那么对不可见字符做分隔符就需要用八进制的ASCII码来转义。

(10)Insert

根据语法Insert必须加“OVERWRITE”关键字,也就是说每一次插入都是一次重写。

其他优化:

1).Left Semi Join实现in/exists子查询:

SELECT A.* FROM A LEFT SEMI JOIN B ON(A.KEY = B.KEY AND B.KEY > 100);

等同于SELECT A.* FROM A WHERE A.KEY IN(SELECT B.KEY FORM B
WHERE B.KEY > 100);

作用:map端用group by减少流入reduce端的数据量

2).Bucket Map Join:

set hive.optimize.bucketmapjoin = true;

和Map join一起工作;

所有join的表都做列分桶,同时大表桶的数量是小表桶的整数倍;

做bucket的列必须是join的列;

SELECT /*+MAPJOIN(a,c)*/ a.*, b.*,
c.*

a join b on a.key = b.key

join c on a.key=c.key;

在现实的生产环境中,会有成百上千个buckets;

3).Skew join:

join时数据倾斜,造成Reduce端OOM

set hive.optimize.skewjoin = true;

set hive.skewjoin.key = 阀值;

当JOIN得到的map超过阀值时,将内存中的a-k1/b-k1数据分别存入hdfs中,然后遍历完后再对hdfs上的两块数据做Map Join,和其它key一起组成最后结果。

Hive查询进

通过hive提供的order by子句可以让最终的输出结果整体有序。但是因为Hive是基于hadoop之上的,要生成这种整体有序的结果,就必须强迫Hadoop只利用一个Reduce来完成处理。这种方式的副作用就是回降低效率。如果你不需要最终结果整体有序,你就可以使用sort by子句来进行排序。这种排序操作只保证每个Reduce的输出是有序的。如果你希望某些特定行被同一个Reduce处理,则你可以使用distribute by子句来完成。【Hiveselect top N的问题。】

Hive> select subject,score,student from score where dt='2012' orderby subject,socre desc ;

使用distribute by + sort by。distribute by可以让相同科目的成绩记录发送到同一个reducer,而sort by可以在reducer端对记录做排序。

Hive> select subject,score,student from score where dt='2012' distribute by subject sort by subject asc, socre desc;

连接join

内链接inner join

外连接left/right/full outer join

半连接 left semi join

Map连接(map join):

当一个表非常小,足以直接装载到内存中去时,可以使用map连接以提高效率,比如:Select /*+mapjoin(teacher) */ a.stuNo,b.teacherNamefrom student a join teacher b on a.classNo = b.classNo;

以上红色标记部分采用了C的注释风格。当连接时用到不等值判断时,也比较适合Map连接。具体原因需要深入了解Hive和MapReduce的工作原理。

Top N

开窗函数:row_number() over(partition by col_a order by col_b) rank

select product,category,revenue from(

select product,category,revenue,

row_number() over(partition by catrgory order by revenue desc)rank

from mytable)t

where t.rank<=3;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: