Hive
1.hive简介:
hive是基于hadoop的一个数据仓库工具,它可以将结构化数据文件映射为一张数据库表,并提供hive SQL查询功能;hive的本质是将hive SQL转化为MapReduce程序;使用hive来完成离线数据分析,比直接使用MapReduce开发效率高
2.hive与hadoop的关系:
hive利用HDFS存储结构化数据(利用mysql存储元数据),利用MapReduce查询分析数据。
3.hive的组件:
* 用户接口: 用户访问hive的窗口
* 元数据仓库: 通常使用mysql来存储元数据,元数据中保存了结构化数据文件和hive逻辑库,表的映射关系;hive默认自带derby来存储元数据,但是不同路径启动derby都会对应一个新的元数据长路,因此不利于共享数据;所以通常让hive集成mysql
* 解释器,编译器,优化器,执行器: hive SQL转化为MapReduce程序
4.hive的启动
hive服务端: bin/hiveserver2
用户接口: bin/beeline -u jdbc:hive2://192.168.255.121:10000 -n root
5.hive数据模型:
hive将数据存储到HDFS中,没有专门的数据存储格式约束;因此在创建逻辑表的时候,必须指定分隔符,hive才能映射成功,否则查询的结果都是Null;默认情况下分隔符是'\001'(不可见分隔符)
* db:在hdfs中表现为/user/hive/warehouse/目录下一个文件夹
* table:在hdfs中表现所属db目录下一个文件夹
* external table:指定结构化数据文件在hdfs下的路径;如果不指定,数据文件必须存放在table目录下才能被映射分析
* partition:在hdfs中表现为table目录下的子目录,指定partition能够指定TextInputFormat扫描文件子目录,提高查询效率
* bucket:在hdfs中表现为同一个表目录下根据hash散列之后的多个文件,将一个文件Hash取模拆分;分桶能够提升join连接查询的效率
6.注意事项:
* 创建表的时候必须指定分割符,ROW FORMAT DELIMITED
* 分区字段名不能跟表中字段名重复;分区字段是一个虚拟的字段,分区字段值由装载数据是指定
* 分桶字段名必须跟表中的某个字段名重复;指定的这个分桶字段就是reducer数据分区时所用来判断的key
* 将数据加载Load到表中,hive实际上是把数据文件复制到了逻辑表所在目录下
Hive SQL
1.创建表:
*内部表
create table t_t1(id int,name string);
*外部表
create external table t_t2(id int,name string) location '/hdfsDir/';
2.分区表:(PARTITIONED BY)
* 创建单分区表:
create table t_t3(id int,name string) partitioned by (dirone string);
* 创建多分区表:
create table t_t4(id int,name string) partitioned by (dirone string,dirtwo string);
3.创建表并指定分隔符(ROW FORMAT DELIMITED)
* 根据","来拆分
create table t_t5(id int, name string) partitioned by (dirone string) row format delimited fields terminated by ',';
eg:
1,张三
2,李四
* 根据复杂类型拆分
create table t_t6(id int,name string,hobby map<string,string>)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':' ;
eg:
1,张三,唱歌:非常喜欢-跳舞:喜欢-游泳:一般般
2,李四,打游戏:非常喜欢-篮球:不喜欢
4.分桶表(cluster by into num buckets)
set hive.enforce.bucketing = true;
set mapreduce.job.reduces=5;
create table t_t7(id int,name string,sex string,age int,address string)
clustered by(age)
sorted by(id DESC)
into 5 buckets
row format delimited
fields terminated by ',';
insert overwrite table t_t7
select * from student cluster by(age);
5.导入数据Load data
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO
TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
INPATH: 指HDFS目录树下的目录
LOCAL INPATH: 指hive server所在的linux目录
INTO: 如果逻辑表已经存在装载的文件,那么自动对新添加的文件改名
OVERRIDE INTO: 如果逻辑表已经存在装载的文件,那么就覆盖已存在的文件
eg:
LOAD DATA local INPATH '/export/testdata/a.txt' INTO TABLE student partition(dirone='onedir');
6.分桶且排序
[GROUP BY col_list [HAVING condition]]
[CLUSTER BY col_list
| [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list]
]
[LIMIT number]
1.order by先对数据进行全局排序,再将排序后的数据交给mr程序,大量数据时效率低
2.sorted by是在map
3.distribute by将数据分发给不同的reducer
4.cluster by将数据分发给不同的reducer且对数据进行排序,cluster by = distribute by + sort by