这篇文章主要为大家展示了“hive是干什么的”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“hive是干什么的”这篇文章吧。
Hive是啥?
Hive是建立在hadoop上的数据仓库基础框架,主要用于分析与统计数据。他也是一个Sql解析引擎,将Sql语句转换成mr程序来运行,从而得到统计数据。他的语法大部分遵循Sql99,所以对有着数据库经验的人来说很友好。他们不用写繁琐的MR程序,通过sql语句即可得到所需的数据。Hive中的表就是hdfs上的目录,一个表名对应一个目录名,数据以文件形式存放在目录下。因为hive存储基于hdfs,所以依赖于hadoop,在没有hadoop的环境下hive是跑不了的。它并没有专门的存储格式,却有着存储结构,比如数据库,表,视图之类。
Hive的系统架构。
首先对外提供了三种用户接口,CLI,JDBC/ODBC,WebUI,所以用户可通过三种形式来操作hive。用户访问了,必然执行sql语句,所以hive要有编译器,解释器,优化器,执行器。接着生成了MR任务,也就是执行计划,去访问ResourceManger和NameNode来处理程序。其中hive的MetaStore,也就是元数据存储依赖于数据库。默认是自带的derby数据库,可是这个数据库只支持一个会话,所以可通过更改配置将其更改为用MySql存储。
Hive中sql的执行过程
首先用户通过接口向hive提交了sql语句,接着发给驱动来解析语句,然后交给编译器编译语句,再找metastore查询涉及到的元数据,生成执行计划交还给驱动,驱动把计划交给执行引擎执行,执行引擎如果发现这是类似于ddl语句,则要往metastore写入元数据,如果是涉及到计算的语句,如count(*)之类的则要交给resourcemanger来执行mr程序,如果是查询字段之类的,则直接找namenode拿到所需数据即可。等到程序执行完或者数据拿到,则将执行结果交换执行引擎,执行引擎给用户接口。
Hive三种用户接口之CLI
其实也就是命令行模式,直接执行hive,或者执行hive --service cli。这样就可打开hive命令行。你可以输入show tables;或者create table语句来验证是否成功。(注意,上面说到hive表其实就是hdfs的目录,该目录的路径是由你的配置文件项hive.metastore.warehouse.dir所指定的)。在你启动hive的时候,你可以加一些参数,来多功能的使用。比如你用 hive -d name=xiaoming,则就等于设置了一个name变量,变量值为xiaoming,在hive中可以调用该变量${name}。或者说你就想执行一条语句,并不想进入hive命令行,你可以 hive -e “show tables”。或者你想把执行结果写入文件中,则hive -e “show tables”> a.txt。举例如下
$>hive -e "" 不用进入hive界面,在双引号里使用hql语句即可执行,省略了开启hive的时间。不过执行完还在linux界面
$>hive -e "">aaa 同上,不过就是把执行的结果写入aaa中
$>hive -S -e "">aaa 同上,加了个静默模式,就是少了一些日志提示,比如执行的时间什么的,大量操作的话,可以省略部分时间。
$>hive -f file File用一个写入了hql语句的文件的位置代替,然后就执行了。
$>hive -i /home/my/hive-init.sql 就是执行完过后不是回到了linux界面,而使留在了hive界面
hive>source file 跟-f差不多,不过是在hive界面执行。
你也可以用 hive --hiveconf 加上要指定的配置文件项来在当前会话中使用你指定的配置,如
hive --hiveconf hive.cli.print.current.db=true;
你也可以在hive命令行下使用set命令来完成与hiveconf相同的功能,如set hive.cli.print.current.db=true;
如果你觉得这样配置好麻烦,想一启动的时候就自动应用这些配置,那么你可以在你操作系统的用户目录下,也就是你用cd命令到的目录下,建立文件.hiverc(不要忘记.)。文件内容就是set命令内容。
hive用户接口之JDBC
用这种当时的时候,注意看自己的hive是1版本还是2版本,可以通过hive下的bin看是hiveserver还是hiveserver2来确定。
运行代码之前需要在命令行中启动服务,hive --service hiveserver2,代码如下
package com.shixin.hivejdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class Hivetest { public static Connection getConnection(){ Connection con=null; try { //若是1版本,则为org.apache.hadoop.hive.jdbc.HiveDriver Class.forName("org.apache.hive.jdbc.HiveDriver"); //注意这里是hive2 con=DriverManager.getConnection("jdbc:hive2://115.28.138.100:10000/default", "hadoop", "hadoop"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return con; } public static void main(String[] args) { Connection con=getConnection(); Statement sta=null; if(con!=null){ try { sta=con.createStatement(); ResultSet rs=sta.executeQuery("show tables"); while(rs.next()){ System.out.println(rs.getString(1)); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
hive之复合数据类型
hive中的基本数据类型与mysql大致形同,主要是多出了三种复合数据类型。分别为Array,Struct,Map。如何使用请看例子。
建表
create table t8(
id int,
info struct<name:string,age:int>,
subject array<int>,
scores map<string,float>)
row format delimited
fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':'
;
(field那句表示字段分隔符,collection表示复合数据类型中内部分隔符,map表示map类型的键值对分隔符)
导入数据
load data local inpath '/home/hadoop/a.txt' into table t8;
其中a.txt数据为
1 sx,21 23,45,32,45 english:94.2,math:99
2 shuainan,22 43,21,32 english:95.2,math:96
查看数据
select * from t8;
t8.id t8.info t8.subject t8.scores
1 {"name":"sx","age":21} [23,45,32,45] {"english":94.2,"math":99.0}
2 {"name":"shuainan","age":22} [43,21,32] {"english":95.2,"math":96.0}
如果分别查询符合数据类型某个值的话,语句为
select info from t8;
select info.sx from t8;
select info.name from t8;
select subject from t8;
select subject[2] from t8;
select subject[3] from t8;
select scores from t8;
select scores['english'] from t8;
7.hive中的一些ddl语句
数据库定义,create database。。。(注意一点,hive启动时默认是default数据库)
表定义,create table。。。。,当然除了这个基础语句,还有create table t2 like t1;只复制t1的表结构,不复制数据。
列定义,其实也就是列的修改
hive>ALTER TABLE t3 CHANGE COLUMN old_name new_name String COMMENT '...' AFTER column2;
ALTER TABLE t3 ADD COLUMNS(gender int);
replace(没有删除列,不过可以试试replace,不过不建议,因为他就等于重新建立表结构,比如你原有两个字段,Replace一个字段,replace过后你就只剩一个字段)
8.外部表与内部表
上述的表的定义,是内部表的定义。那么外部表如何定义的呢?
create external table t11 (id int,name string) row format delimited fields terminated by '\t';
对,仅仅加了个external,查看对应的hdfs的目录,多了个t11目录。接着加载数据
load data local inpath '/home/hadoop/aaa' into table t11;
用select查看,可以查看到数据,看hdfs对应的t11目录下,多了个aaa文件。这一切好像都和内部表一样啊。那么他们两个的区别是什么?我们对内部表和外部表都用drop table操作,结果发现,内部表的hdfs上的表目录消失,而外部表的表目录数据依旧存在。所以,我们可知 删除外部表只删除metastore的元数据,不删除hdfs中的表数据(就是warehouse目录下的)。
当表的定义语句是这样的
hive> create external table exter_table(
> id int,
> name string,
> age int,
> tel string)
> location '/home/wyp/external';
也就是说你加了location,指定了表的存放路径,此时不论有没有external(也就是说不论是内部表还是外部表),他会在指定路径创建指定文件夹,而不是说像原来一样在warehouse下以表名为目录创建。此时如果你用load命令导入数据,数据文件会存放到你指定的路径下。
9.分区表
分区表也就是把数据分类,分组,类似于groupby,将不同的分区以不同的文件夹形式表现出来。它的意义就是优化查询。查询时如果用分区字段,则会加快查询速度。
创建分区表
create table t12 (id int,name string) partitioned by (date string) row format delimited fields terminated by '\t';
添加分区
alter table t12 add partition(data='20160103');
alter table t12 add partition(date='20160102');
此时,t12目录下多出了data=20160102和 data=20160103文件夹。
加载数据
load data local inpath '/home/hadoop/aaa' into table t12 partition(date='20160103');
10.视图和索引
hive中也可以像mysql一样创建视图和索引
create view v1 AS select t1.name from t1;
创建索引
create index t1_index on table t1(name)as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild in table t1_index_table; ( as指定索引器)
重建索引
alter index t1_index on t1 rebuild;(当数据有更改时,需要重建索引)
显示索引
show formatted index on t1;
删除索引
drop index if exists t1_index on t1;
11.装载数据的方式
从文件中装载数据
hive>LOAD DATA [LOCAL] INPATH '...' [OVERWRITE] INTO TABLE t2 [PARTITION (province='beijing')];(不加local则从hdfs上面取,overwrite是覆盖的意思,如果是分区表则要加上partition)
通过查询表装载数据
hive>INSERT OVERWRITE TABLE t2 PARTITION (province='beijing') SELECT * FROM xxx
WHERE xxx (同样,如果你是分区表,分区信息加上,他会把select查询的数据以文件的形式存放到t2对应的目录下,你的select语句所查询的属性要能和t2对的上)
hive>FROM t4
INSERT OVERWRITE TABLE t3 PARTITION (...) SELECT ...WHERE...
INSERT OVERWRITE TABLE t3 PARTITION (...) SELECT ...WHERE...
INSERT OVERWRITE TABLE t3 PARTITION (...) SELECT ...WHERE... (上面的升级版)
还有一种动态分区加载
hive>INSERT OVERWRITE TABLE t3 PARTITION(province='bj', city)
SELECT t.province, t.city FROM temp t WHERE t.province='bj';
(你的city分区字段属性要对得上,然后执行后就会在province=bj下创建city=t.city的目录分区。其中province的值可以不存 在,他会新建。这种情况是不开启动态分区的时候支持的)
如果你的语句是这样的
hive>INSERT OVERWRITE TABLE t3 PARTITION(province, city)
此时要开启动态分区支持
hive>set hive.exec.dynamic.partition=true;
hive>set hive.exec.dynamic.partition.mode=nostrict;
hive>set hive.exec.max.dynamic.partitions.pernode=1000;
12. hive中的函数
hive中有像mysql中的函数,比如max(),min()等。hive中也可以自定义函数,你把所需要的功能用java代码编好,打jar包即可。具体步奏如下
a)把程序打包放到目标机器上去;
b)进入hive客户端,添加jar包:hive>add jar /run/jar/udf_test.jar;
c)创建临时函数:hive>CREATE TEMPORARY FUNCTION add_example AS 'hive.udf.Add';
(add_example是你要取得函数名字,‘’里面的是你的类路径,比如com.shixin.hive.MyUp)
udf代码如下(小小的转换大写功能)
package com.shixin.hive;
import org.apache.hadoop.hive.ql.exec.UDF;
public class MyUp extends UDF{
public String evaluate(String word){
if(word==null||word.equals("")){
return null;
}else{
return word.toUpperCase();
}
}
}
以上是“hive是干什么的”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。