-Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射成一张表,并提供SQL查询功能
因为是基于hdfs,数据默认存放在/usr/warehouse中
-Hive表是HDFS的一个文件目录,一个表名对应一个目录名,如果有分区表的话,则分区值对应子目录名
进入Hive客户端
./bin/hive
hive命令交互的几种方式
#hive -e "SQL"
#hive -f src/hive.sql (通过读取含有SQL语句的文件来执行,不一定是sql为后缀)
#hive -f src/hive.sql > src/data.txt (将本地SQL语句的结果写入到本地data.txt文件中去)
#cat .hivehistory 里面存放所有在hive中执行的命令
基础命令:
清屏Ctrl+L (or) !clear
注释 --
查看HDFS上的文件 hive>dfs -ls /;
执行系统操作命令 hive>!命令; 例如:hive>!cat /home/hadoop/t.txt
hive>show functions; 查看hive中的所有内置函数
hive>desc function extended function_name; 内置函数的用法
hive>desc extended table_name; 查看表的所有信息
hive>desc formatted table_name; 查看表的所有信息
hive>show databases like 'user*' 查询数据库,可使用通配符
hive>drop database db_name [cascade]; 如果数据库中有表存在,则需要添加cascade
Hive的基本数据类型
tinyint/smallint/int/bigint :整数类型
float/double : 浮点型
boolean : 布尔类型
string :字符串类型
内部表:不加关键字external ,创建的表就是内部表
内部表的缺陷:如果删除表,则hdfs上的数据也会删除
创建内部表:
hive>create table [if not exists] person
>row format
>delimited fields terminated by ',' //行分隔符
>collection items terminated by '\n' //列分隔符,默认为换行符,一般不写
>stored as TEXTFIELD //信息存储格式,默认为文本格式
>location '/user/hive/warehouse/'; //设置表的存储位置,在hdfs上
外部表:加关键字external ,数据可以在hdfs的任意位置, 只需要通过关键字location
删除表不会影响hdfs上的数据
创建外部表:
hive>create external table [if not exists] person
>row format
>delimited fields terminated by ',' //行分隔符
>collection items terminated by '\n' //列分隔符,默认为换行符,一般不写
>stored as TEXTFIELD //信息存储格式,默认为文本格式
>location '/user/hive/warehouse/'; //设置表的存储位置,在hdfs上
分区表:对数据进行分区,分区字段是虚拟的,里面不存储任何数据,分区字段
不能够和真实字段重复。分区字段在底层(hdfs)所显示的就是以分区
字段命名的文件夹
创建分区表:(partition要在row前面)
hive>create table person_part(id int,name string,age int)
>partitioned by (sex string)
>row format
>delimited fields terminated by ',';
>stored as textfile;
查看表的分区
hive>show partitions person_part;
导入数据
hive>load data local inpath '/root/hive.dat' into table person_part partition(sex='femal')
如果创建一个分区表,不导入数据,hdfs没有创建分区的文件夹,如果手动创建文件夹,并导入数据分区表无法读取数据,此时可以对分区表进行修复或者添加一个分区
hive>msck repair table table_name; 对分区表修复
hive>alter table table_name add partition(分区字段='.'); 添加一个分区(分区字段不变)
桶表
hive>set; //查看当前所有的配置信息(可以设置属性,但是只在当前会话生效)
设置开启分桶表 hvie>set hive.enforce.bucketing = true;
设置分桶表的个数 hive>set mapreduce.job.reduces = 4;(设置为3个)
创建分桶表 :分桶需要指定字段 ,这个字段一定是表中的某个字段
hive>create table person_bucket(id int,name string,age int)
>prititioned by (sex string) //根据性别分区
>clustered by(age) into 4 buckets (对年龄进行哈希运算来分,结果放入4个桶中)
>row format
>delimited fields terminated by ','
>stored as textfile;
分桶表无法直接插入数据,只能通过查询其他字段相同的表来复制数据(insert + select 语句)
hive>insert into table person_part partition(sex="male") select * from person_part;
Load 导入数据
在将数据加载到表中是,Hive不是进行任何转化,加载操作是将数据
文件移动到Hive表对应的位置的纯复制/移动操作
语法结构
load data [local] inpath 'filepath' [overwrite]
into table table_name [partition(partcol1=val1,partcol2=val2..)]
说明:如果没有local,路径为hdfs路径--如果有local,路径为本地路径
如果没有overwrite,为添加数据--如果有,为覆盖数据
如果是本地文件 load帮你复制一份到hive指定的位置去 跟表产生映射关系
如果是hdfs上的文件 load会帮你把数据移动到指定的位置去 跟表产生映射关系
如果路径为一个目录,则将目录下所有文件移动到表中
load过程中,不会针对数据进行任何修改操作,因为特别要提前把数据中的类型 分隔符搞清楚
导出数据
1、导出数据到本地(path为目录路径)
hive>insert overwrite local directory 'path'
>row format delimited fields terminated by '\t' //导出数据分隔符
>select * from table_name;
2.导出在hdfs(不可使用row format等用法,path为目录路径)
Hive>insert overwrite directory '/path'
>select * from table_name;
3.导出到另一个表(表的格式需要相同)
Hive>insert into table person select * from table_name;
4.保存到本地
#hive -e "select * from db_name.table_name" > /home/hadoop/data.txt
5.将hdfs上的数据导入到表中
hive>import table table_name from '/user/data/..';
6.将表中数据导出到hdfs上
hive>export table table_name to '/user/..';
Hive自定义函数
1.创建JavaProject项目
2.导入hadoop-common.2.6.4.jar和hive-exec-1.2.1.jar包
3.创建java,继承UDF,重载evaluate方法
4.导出为myudf.jar包
5.将jar包添加到hive的classpath中
hive>add JAR /home/hadoop/myudf.jar
6.设置函数名
hive>create temporary function 函数名 as '包名.类名';
**************************************************************
数据压缩snappy
tar -zxvf 2.5.0-native-snappy.tar.gz -C ./snappy 解压到当前snappy新建目录下
cd $HADOOP_HOME$/lib
mv native ./250-native 修改native
mkdir nativ 新建native目录
cp src/snappy/* ./native 将snappy下的压缩包复制到新建的native目录中
hadoop checknative 查看安装的是否可行
运行mapreduce压缩输出数据
hadoop jar wordcount.jar map_reduce.WordCount
-Dmapreduce.map.output.compress=true
-Dmapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec
/input /output
在hive设置压缩数据
hive>set Dmapreduce.map.output.compress=true;
hive>set Dmapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
hive的几种存储格式
textfile 数据文件大
parquet 原数据的70%
orc 原数据的13%
在建表时创建:
create table page_views_parquet(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string)
row format delimited fields terminated by '\t'
stored as parquet;
orc 和 parquet表的数据需要使用textfile表的查询来插入
insert into table page_views_parquet select * from page_views;
通过查询速度对比,orc>parquet>textfile
select session_id,count(*) cnt from page_views group by session order by cnt desc limit 30;
select session_id from page_views_orc limit 30;
读取hdfs文件大小
hadoop fs -du -h /user/hive/warehouse/school.db/..
通过使用snappy在建表时对orc表数据压缩
create table page_views_orc_snappy(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string)
row format delimited fields terminated by '\t'
stored as orc tblproperties("orc.compress"="SNAPPY");
在实际的项目开发中,hive表的数据
*存储格式
orcfile / qarquet
*压缩
snappy
***************************************************
Hive优化
->当使用"*"查询表数据和使用"limit"时,以及查询分区表中的分区字段时,不会运行mapreduce
->大表拆分:如果一个表中的无用字段过多,可以创建一个子表
create [external] table table_name as select_statement;
->外部表、分区表:结合使用,多级分区
create [external] table table_name(字段..)
partitioned by(name type)
row format row_format;
->数据
存储格式(textfile、orcfile、parquet)
数据压缩(snappy)
->SQL优化