赞
踩
1:hive简介
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。
2:hive组件
用户接口:包括 CLI、JDBC/ODBC、WebGUI。(访问hive)
元数据存储:通常是存储在关系数据库如 mysql , derby中。(存储hive表单的元数据)
解释器、编译器、优化器、执行器。(完成查询语句分析、编译、优化以及生成查询计划,调用mapreduce执行,存储到hdfs)
3:与传统数据库对比
4:hive数据存储
1、Hive中所有的数据都存储在 HDFS 中,没有专门的数据存储格式(可支持Text,SequenceFile,ParquetFile,RCFILE等)
2、只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据。
3、Hive 中包含以下数据模型:DB、Table,External Table,Partition,Bucket。
db:在hdfs中表现为${hive.metastore.warehouse.dir}目录下一个文件夹
table:在hdfs中表现所属db目录下一个文件夹
external table:外部表, 与table类似,不过其数据存放位置可以在任意指定路径
普通表: 删除表后, hdfs上的文件都删了
External外部表删除后, hdfs上的文件没有删除, 只是把表单删除了
partition:在hdfs中表现为table目录下的子目录(分区字段不能和表中的字段重复)
bucket:桶, 在hdfs中表现为同一个表目录下根据hash散列之后的多个文件, 会根据不同的文件把数据放到不同的文件中
5:hive 示例
5.1 创建内部表
- hive> create table fz
- > (id int,name string,age int,tel string)
- > ROW FORMAT DELIMITED
- > FIELDS TERMINATED BY ','
- > STORED AS TEXTFILE;
5.2创建外部表
hive> create external table fz_external_table(id int,name string,age int,tel string)
> ROW FORMAT DELIMITED
> FIELDS TERMINATED BY ','
> STORED AS TEXTFILE
> location '/user/hive/external/fz_external_table';
建外部表时要加external关键字,我在建表时指定了location,当然也可以不指定,不指定就默认使用hive.metastore.warehouse.dir指定的路径
load data local inpath '/Users/FengZhen/Desktop/Hadoop/hive/testfile/fz_external_table.txt' into table fz_external_table;
5.3创建分区表
create table invites (id int, name string) partitioned by (ds string) row format delimited fields terminated by 't' stored as textfile;
将数据添加到时间为 2013-08-16 这个分区中:
load data local inpath '/home/hadoop/Desktop/data.txt' overwrite into table invites partition (ds='2013-08-16');
5.4创建分桶表
- create table stu_buck(sno int,sname string,sex string,sage int,sdept string)
- clustered by(sno)
- sorted by(sno DESC)
- into 4 buckets
- row format delimited
- fields terminated by ',';
- #设置变量,设置分桶为true, 设置reduce数量是分桶的数量个数
- set hive.enforce.bucketing = true;
- set mapreduce.job.reduces=4;
- #开会往创建的分通表插入数据(插入数据需要是已分桶, 且排序的)
- #可以使用distribute by(sno) sort by(sno asc) 或是排序和分桶的字段相同的时候使用Cluster by(字段)
- #注意使用cluster by 就等同于分桶+排序(sort)
- insert into table stu_buck
- select sno,sname,sex,sage,sdept from student distribute by(sno) sort by(sno asc);
5.6 导入数据
四种种方式:
sql中的insert into语句:insert into tableName values(.....)
sql中的insert select语句 :
insert into table stu_buck select sno,sname,sex,sage,sdept from student distribute by(sno) sort by(sno asc);
sql中创建表直接导入数据:
create table t_display_access_info as
select remote_addr,firt_req_time,last_req_time,
case stay_long
when 0 then 30000
else stay_long
end as stay_long
from t_display_access_info_tmp;
通过文件导入:
load data local inpath '/Users/FengZhen/Desktop/Hadoop/hive/testfile/fz_external_table.txt' overwrite
into table fz_external_table;
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO
TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
说明:
相对路径,例如:project/data1
绝对路径,例如:/user/hive/project/data1
包含模式的完整 URI,列如:
hdfs://namenode:9000/user/hive/project/data1
3.LOCAL关键字
如果指定了 LOCAL, load 命令会去查找本地文件系统中的 filepath。
如果没有指定 LOCAL 关键字,则根据inpath中的uri查找文件
4.OVERWRITE 关键字
如果使用了 OVERWRITE 关键字,则目标表(或者分区)中的内容会被删除,然后再将 filepath 指向的文件/目录中的内容添加到表/分区中。
如果目标表(分区)已经有一个文件,并且文件名和 filepath 中的文件名冲突,那么现有的文件会被新文件所替代。
5.7 导出数据到hdfs
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 SELECT ... FROM ...
5.8 Hive自定义函数和Transform
当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function)。
5.9 自定义函数类别
UDF 作用于单个数据行,产生一个数据行作为输出。(数学函数,字符串函数)
UDAF(用户定义聚集函数):接收多个输入数据行,并产生一个输出数据行。(count,max)
5.10 UDF开发实例
1、先开发一个java类,继承UDF,并重载evaluate方法
package cn.itcast.bigdata.udf import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.Text;
public final class Lower extends UDF{ public Text evaluate(final Text s){ if(s==null){return null;} return new Text(s.toString().toLowerCase()); } } |
2、打成jar包上传到服务器
3、将jar包添加到hive的classpath
hive>add JAR /home/hadoop/udf.jar;
Hive>create temporary function toprovince as 'cn.itcast.bigdata.udf.ToProvince'; |
Select strip(name),age from t_test;
5.11 Transform实现
Hive的 TRANSFORM 关键字提供了在SQL中调用自写脚本的功能
适合实现Hive中没有的功能又不想写UDF的情况
使用示例1:下面这句sql就是借用了weekday_mapper.py对数据进行了处理.
CREATE TABLE u_data_new ( movieid INT, rating INT, weekday INT, userid INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
add FILE weekday_mapper.py;
INSERT OVERWRITE TABLE u_data_new SELECT TRANSFORM (movieid, rating, unixtime,userid) // transform读取一行数据传到py脚本中 USING 'python weekday_mapper.py' AS (movieid, rating, weekday,userid) FROM u_data; |
其中weekday_mapper.py内容如下
#!/bin/python import sys import datetime
for line in sys.stdin: line = line.strip() movieid, rating, unixtime,userid = line.split('\t') weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday() print '\t'.join([movieid, rating, str(weekday),userid]) |
使用示例2:下面的例子则是使用了shell的cat命令来处理数据
FROM invites a INSERT OVERWRITE TABLE events SELECT TRANSFORM(a.foo, a.bar) AS (oof, rab) USING '/bin/cat' WHERE a.ds > '2008-08-09'; |
6:hive创建表语法
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name ####EXTERNAL 外部表 IF NOT EXISTS判断是否存在
[(col_name data_type [COMMENT col_comment], ...)] #### COMMENT 字段注释
[COMMENT table_comment] #### COMMENT 表注释
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] ###分区字段 分区字段是一个伪字段
[CLUSTERED BY (col_name, col_name, ...) ####
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] 一起的
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]
字段含义:
SEQUENCEFILE|TEXTFILE|RCFILE
如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。
2.ROW FORMAT
DELIMITED [FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]
| SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]
用户在建表的时候可以自定义 SerDe 或者使用自带的 SerDe。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的 SerDe。在建表的时候,用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的 SerDe,Hive通过 SerDe 确定表的具体的列的数据。
3.CLUSTERED BY:
对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive也是 针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。 这个有点类似于mapreduce的那个分区操作
注:1、order by 会对输入做全局排序,因此只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。
2、sort by不是全局排序,其在数据进入reducer前完成排序。因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by只保证每个reducer的输出有序,不保证全局有序。
3、distribute by(字段)根据指定的字段将数据分到不同的reducer,且分发算法是hash散列。
4、Cluster by 除了具有Distribute by的功能外,还会对该字段进行排序。因此,常常认为cluster by = distribute by + sort by
因此,如果分桶和sort字段是同一个时,此时,cluster by = distribute by + sort by
分桶表的作用:最大的作用是用来提高join操作的效率;
(思考这个问题:
select a.id,a.name,b.addr from a join b on a.id = b.id;
如果a表和b表已经是分桶表,而且分桶的字段是id字段
做这个join操作时,还需要全表做笛卡尔积吗?)
使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。