Hive的基本原理与使用


Hive的基本原理与使用

本文转自:http://tiechou.info/?p=33

简介

Hive是基于Hadoop构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据。Hive可以将结构化的数据存储在数据仓库中,通过自己的SQL去查询分析需要的内容,这套SQL简称Hive SQL。它与关系型数据库的SQL略有不同,但支持了绝大多数的语句如DDL、DML 以及常见的聚合函数、连接查询、条件查询。

Hive在Hadoop的架构体系中承担了一个SQL解析的过程,它提供了对外的入口来获取用户的指令然后对指令进行分析,解析出一个MapReduce程序组成可执行计划,并按照该计划生成对应的MapReduce任务提交给Hadoop集群处理,获取最终的结果。
安装

Hive需要Hadoop的支持,也就是说在安装Hive之前需要正确安装Hadoop。一般我们会将Hive安装到NameNode所在主机上,这里假设使用root用户进行安装,Hive的安装过程很简单,网上有很多安装方式:

1[root@192.168.1.111] # 去到hadoop的目录,使用hadoop的项目根目录
2[root@192.168.1.111] cd /opt/hadoop
3[root@192.168.1.111] # 下载项目包(去官网(http://hadoop.apache.org/)下载Hadoop项目)
4[root@192.168.1.111] wget http://www.apache.org/dist/hadoop/hive/hive-0.5.0/hive-0.5.0-dev.tar.gz
5[root@192.168.1.111] # 解压
6[root@192.168.1.111] tar xzvf hive-0.5.0-dev.tar.gz
7[root@192.168.1.111] # 进入目录
8[root@192.168.1.111] cd hive-0.5.0-dev
9[root@192.168.1.111] # 与Hadoop的安装一样,我们应该习惯性的将安装目录写入环境变量
10[root@192.168.1.111] export HIVE_HOME=`pwd`
11[root@192.168.1.111] # 也可以将环境变量设置到/etc/profile中


配置

Hive的必要配置相当简单,只需要声明$HADOOP_HOME(请查阅《Hadoop安装》文档)这个环境变量就行了。

Hive的核心配置文件$HIVE_HOME/conf/hive-default.xml中有一些对Hive关键配置,一般我们不需要对期进行改动,如果你需要更改这个关键配置,请不要直接更改hive-default.xml这个文件,在同一目录下新建hive-site.xml文件,然后将需要更改的属性配置在这里面即可,配置格式与hive-default.xml一样。

在Hive官方文档中重点提到了Hive的日志配置$HIVE_HOME/conf/hive-log4j.properties,虽然不是必要更改的配置文件,但合理的设置会对我们有一定的帮助,具体配置方法可见官方文档。


使用

Hive提供了一个CLI(Command Line Interface)客户端,我们可以通过CLI进行直观的DDL、DML及SQL操作。以下是CLI使用示例:

1# 这里创建了一个foo表,字段以\001分隔,location指定映射文件位置
2create external table foo
3(
4uid bigint,
5brand_value string
6)
7row format delimited fields terminated by '\001'
8stored as textfile
9location "/group/tbsc-dev/haowen/temp/shpsrch_bshop_brand_value_ssmerge_1011/";
10  
11# 插入数据到 foo表 注意这些语句不要用tab缩进
12INSERT OVERWRITE TABLE foo
13select uid,value_data
14from
15(
16  select t1.uid,t2.value_data
17  from
18     shpsrch_bshop_brand_unfold_ssmerge_1011 t1
19     join sel_shpsrch__base_values t2
20     on t1.brand_id = t2.value_id and t2.ds=20101019
21) a;

也可以在终端界面这样使用

1echo "select * from foo where uid=153702175;" | hive -u root -p root


数据join

之前在数据join的时候遇到过这样一个问题,就是当一个uid 对应多个品牌brand_id 的时候,即:
uid – brand_id1 = brand_id1 – brand_value1
uid – brand_id2 = :
uid – brand_id3 = :
这样join之后的数据会出现:
uid – brand_value1
uid – brand_value1
这个样子相同的多条记录,出现数据重复的现象
如果数据量小的话,最简单的调试办法是 这样:把所有的数据放在一个namenode上面跑

1hive -u root -p root  <<EOF
2  
3# 指定reduced的任务数量
4set mapred.reduce.tasks=1;
5add file /data/tiechou/ssmerge/mod/mod_bshop_brand/script/brand_packed.pl;
6explain
7INSERT OVERWRITE TABLE foo
8  select transform(uid, value_data)
9  using 'brand_packed.pl'
10  as uid,brand_value
11  from
12(
13select t1.uid,t2.value_data
14  from
15     shpsrch_bshop_brand_unfold_ssmerge_1011 t1
16     join sel_shpsrch__base_values t2
17     on t1.brand_id = t2.value_id and t2.ds=1 distribute by t1.uid
18) a;
19set mapred.reduce.tasks=256;
20EOF

上面显然不是最好的办法,不过已经说明问题了,是相同uid被分到多个namenode上join引起的,其实hive是支持clusterBy? | distributeBy? sortBy? 的, clusterBy是 distributeBy? sortBy?的综合

1hive -u root -p root  <<EOF
2  
3add file /data/tiechou/ssmerge/mod/mod_bshop_brand/script/brand_packed.pl;
4INSERT OVERWRITE TABLE foo
5select transform(t3.uid,t3.value_data)
6  using 'brand_packed.pl'
7  as uid,brand_value
8from(
9from shpsrch_bshop_brand_unfold_ssmerge_1011 t1 join sel_shpsrch__base_values t2 on (t1.brand_id = t2.value_id and t2.ds=20101019) select t1.uid,t2.value_data distribute by t1.uid) t3;

最后我们普及一下sql join,在网上找了一个很形象的说明:http://coolshell.cn/articles/3463.html

SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚。Coding Horror上有一篇文章(实在不清楚为什么Coding Horror也被墙)通过 文氏图 Venn diagrams 解释了SQL的Join。


假设我们有两张表。

Table A 是左边的表。

Table B 是右边的表。


其各有四条记录,其中有两条记录是相同的,如下所示:


id name id name

– —- — —-
1 Pirate 1 Rutabaga
2 Monkey 2 Pirate
3 Ninja 3 Darth Vader
4 Spaghetti 4 Ninja


下面让我们来看看不同的Join会产生什么样的结果。

1SELECT * FROM TableA
2INNER JOIN TableB
3ON TableA.name = TableB.name


Inner join

id name id name
– —- — —-
1 Pirate 2 Pirate
3 Ninja 4 Ninja
结果集: 是A和B的交集。


Full outer join

1SELECT * FROM TableA
2FULL OUTER JOIN TableB
3ON TableA.name = TableB.name


id name id name
– —- — —-
1 Pirate 2 Pirate
2 Monkey null null
3 Ninja 4 Ninja
4 Spaghetti null null
null null 1 Rutabaga
null null 3 Darth Vader


结果集: 产生A和B的并集。但是需要注意的是,对于没有匹配的记录,则会以null做为值。


Left outer join

1SELECT * FROM TableA
2LEFT OUTER JOIN TableB
3ON TableA.name = TableB.name


id name id name
– —- — —-
1 Pirate 2 Pirate
2 Monkey null null
3 Ninja 4 Ninja
4 Spaghetti null null


Left outer join 产生表A的完全集,而B表中匹配的则有值,没有匹配的则以null值取代。

1SELECT * FROM TableA
2LEFT OUTER JOIN TableB
3ON TableA.name = TableB.name
4WHERE TableB.id IS null


hive 中实现方式

1select a_id from (
2select a.id as a_id,b.del_id as b_id
3from shop a left outer join del b
4on a.id = b.del_id )c
5where b_id is null;


id name id name
– —- — —-
2 Monkey null null
4 Spaghetti null null


结果集: 产生在A表中有而在B表中没有的集合。

1SELECT * FROM TableA
2FULL OUTER JOIN TableB
3ON TableA.name = TableB.name
4WHERE TableA.id IS null
5OR TableB.id IS null


id name id name
– —- — —-
2 Monkey null null
4 Spaghetti null null
null null 1 Rutabaga
null null 3 Darth Vader


结果集: 产生A表和B表都没有出现的数据集。

还需要注册的是我们还有一个是“交差集” cross join, 这种Join没有办法用文式图表示,因为其就是把表A和表B的数据进行一个N*M的组合,即笛卡尔积。表达式如下:

1SELECT * FROM TableA
2CROSS JOIN TableB

这个笛卡尔乘积会产生 4 x 4 = 16 条记录,一般来说,我们很少用到这个语法。但是我们得小心,如果不是使用嵌套的select语句,一般系统都会产生笛卡尔乘积然再做过滤。这是对于性能来说是非常危险的,尤其是表很大的时候。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值