Hive 基本使用

原始日志在这,是俺们部门大神写的。帮他提一下PR值

1、生成测试数据

说hive只能识别文件中的单字符分割符,所以只能用不可见字符。好吧。下次搞个响喇叭字符,一打开会不会文件自己唱起歌来了? 使用ASCII 06作为分隔符,在bash下用ctrl+v ctrl+f输入(先按ctrl+v,然后按ctrl+F,会出现^F字符。注意不能直接这么输进去)
seq 1 9999999 | awk '{print $1"^F"$1"aaaaaaaaaaaaaaaa"}' > a.txt
我自己生成的供参考
Hive 基本使用 - scjthree - 亚存的博客
 
2、显示和切换库
hive能建不同的库,sql语句和mysql也挺类似
show databases;
use test;
结果如下:
  Hive 基本使用 - scjthree - 亚存的博客
  
3、创建表及插入数据
创建表语法和oracle里类似,但hive没有insert语句,不能直接往表里插数据。数据一般需要从文件中或者sqoop等获得。这里使用文件创建

create table t(id int,msg string) row format delimited fields terminated by '\006' stored as textfile;

关于详细语法,可以看帮助文档或者网上搜一下。这里简单提点一下

row format delimited 指定分隔符,这里指定了006不可见字符作为分隔符

stored用来设置加在的数据类型,一般都是textfile。运行如下:

Hive 基本使用 - scjthree - 亚存的博客

加载数据,已经被成功的分成了两列

Hive 基本使用 - scjthree - 亚存的博客

 

4、分区表

Hive也能分区,这点真的非常强大。(如果对分区不了解,建议先看看oracle分区的相关知识)

create table t2(id int,msg string) partitioned by( indate string) row format delimited fields terminated by '\006' stored as textfile;

Hive 基本使用 - scjthree - 亚存的博客
  它使用了indate字段作为分区字段。这样就可以在不同分区里放不同的数据。
导入数据如下,和上述导入方式很类似,指定对应的分区就可以了。
load data local inpath '/tmp/b.txt' overwrite into table t2 partition(indate="20131228");
Hive 基本使用 - scjthree - 亚存的博客
b.txt是按a.txt的方法生成的文本,数据如下:
Hive 基本使用 - scjthree - 亚存的博客
  
访问方式如下
select count(1) from t2 where indate>='20131228' and indate<'20131229'
 执行了两遍以方便把结果截图进来。可以看到一个分区内有两条记录
Hive 基本使用 - scjthree - 亚存的博客

分区原理:还没时间仔细看,粗看看应该是在hdfs里面生成了两个独立的文件,则运行时,只要运行对应的文件就可以了。

不过在我们集群上一般也就用到2-3台机器,就算加点数据,顶多再加个map,运行时间不会显著增加。所以个人感觉分区对我们现在业务帮助不大

Hive 基本使用 - scjthree - 亚存的博客

 

5、数据导出

insert overwrite local directory '/tmp/t' select * from t;

数据时导出到指定目录下的文件

Hive 基本使用 - scjthree - 亚存的博客

 Hive 基本使用 - scjthree - 亚存的博客

 
6、创建视图
HIVE也能创建视图
create view v_t as select * from t where id>5 order by id asc;
Hive 基本使用 - scjthree - 亚存的博客
Hive 基本使用 - scjthree - 亚存的博客
 

 创建的时候没用MR,查询的时候启动了,所以可以推测创建时只保存了元数据,没有真正运行。只有查询的时候才启动Hadoop


7、执行计划

hive语句也有执行计划,雷到了

hive (test)> explain select count(1) from t a join t2 b on (a.id=b.id);

OK

ABSTRACT SYNTAX TREE:

  (TOK_QUERY (TOK_FROM (TOK_JOIN (TOK_TABREF (TOK_TABNAME t) a) (TOK_TABREF (TOK_TABNAME t2) b) (= (. (TOK_TABLE_OR_COL a) id) (. (TOK_TABLE_OR_COL b) id)))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (TOK_FUNCTION count 1)))))

STAGE DEPENDENCIES:

  Stage-1 is a root stage

  Stage-2 depends on stages: Stage-1

  Stage-0 is a root stage

STAGE PLANS:

  Stage: Stage-1

    Map Reduce

      Alias -> Map Operator Tree: --map阶段

        a 

          TableScan

            alias: a

            Reduce Output Operator

              key expressions:

                    expr: id

                    type: int

              sort order: +

              Map-reduce partition columns:

                    expr: id

                    type: int

              tag: 0

        b 

          TableScan

            alias: b

            Reduce Output Operator

              key expressions:

                    expr: id

                    type: int

              sort order: +

              Map-reduce partition columns:

                    expr: id

                    type: int

              tag: 1

      Reduce Operator Tree: --reduce阶段

        Join Operator

          condition map:

               Inner Join 0 to 1

          condition expressions:

            0 

            1 

          handleSkewJoin: false

          Select Operator

            Group By Operator

              aggregations:

                    expr: count(1)

              bucketGroup: false

              mode: hash

              outputColumnNames: _col0

              File Output Operator

                compressed: false

                GlobalTableId: 0

                table:

                    input format: org.apache.hadoop.mapred.SequenceFileInputFormat

                    output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat

  Stage: Stage-2

    Map Reduce

      Alias -> Map Operator Tree:

        hdfs://hc1:9000/tmp/hive-hc/hive_2013-12-30_14-05-40_946_5561877030225943803/-mr-10002 

            Reduce Output Operator

              sort order: 

              tag: -1

              value expressions:

                    expr: _col0

                    type: bigint

      Reduce Operator Tree:

        Group By Operator

          aggregations:

                expr: count(VALUE._col0)

          bucketGroup: false

          mode: mergepartial

          outputColumnNames: _col0

          Select Operator

            expressions:

                  expr: _col0

                  type: bigint

            outputColumnNames: _col0

            File Output Operator

              compressed: false

              GlobalTableId: 0

              table:

                  input format: org.apache.hadoop.mapred.TextInputFormat

                  output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat

  Stage: Stage-0

    Fetch Operator

      limit: -1

Time taken: 0.576 seconds

这块还不是很熟,先放着

8、自定义函数
这个还是很有用的,比如我们这里有个业务场景需要用到不等连接,HIVE不支持。
业务场景,一个ip库ip_temp表,三个字段如下
startip  endip  country
123      456      China
还有张访问表session_temp,捕获用户的ip,通过IP表去获得这个用户所在的国家
IP
222
在oracle里关联如下
select * from session_temp t1,ip_temp t2 where t2.startip<=t1.ip and t2.endip>=t1.ip;

HIVE里只能用自定义函数的方式实现
首先要编写个java的函数类,继承自UDF类
   
   
  1. package com.zy.hive.function;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import org.apache.hadoop.hive.ql.exec.UDF;      
  7. public class range extends UDF{  
  8.     //构建IP查询库  
  9.     private static List<IpRange> ipLib = new ArrayList<IpRange>();  
  10.     static{  
  11.         for(int i=0;i<5695104;i++){  
  12.             ipLib.add(new IpRange(i,i+5,"USA"+i));  
  13.         }  
  14.     }  
  15.     //调用时执行的函数  
  16.     public String evaluate(int ip){  
  17.         IpRange ir;  
  18.         for(int i=0;i<ipLib.size();i++){  
  19.             ir = ipLib.get(i);  
  20.             if(ip>=ir.getStartip() && ip <= ir.getEndip()){  
  21.                 return ir.getCountry();               
  22.             }  
  23.         }  
  24.         return null;  
  25.     }  
  26.       
  27.     public static void main(String[] args) {  
  28.         range a = new range();  
  29.         for(int i=0;i<100;i++)  
  30.         System.out.println(a.evaluate(2));  
  31.     }  
  32. }  
  33.   
  34. class IpRange{  
  35.     private int startip;  
  36.     private int endip;  
  37.     private String country;  
  38.     public IpRange(int startip, int endip, String country) {  
  39.         this.startip = startip;  
  40.         this.endip = endip;  
  41.         this.country = country;  
  42.     }  
  43.     public int getStartip() {  
  44.         return startip;  
  45.     }  
  46.     public void setStartip(int startip) {  
  47.         this.startip = startip;  
  48.     }  
  49.     public int getEndip() {  
  50.         return endip;  
  51.     }  
  52.     public void setEndip(int endip) {  
  53.         this.endip = endip;  
  54.     }  
  55.     public String getCountry() {  
  56.         return country;  
  57.     }  
  58.     public void setCountry(String country) {  
  59.         this.country = country;  
  60.     }  
然后导出成jar类,放到hive的一个节点下
加载、创建函数,调用即可
Hive 基本使用 - scjthree - 亚存的博客
 

Hive总的来说还是很强大的,不过用之前也要做充分的调研。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值