hive的介绍
hive的产生 hive的介绍 hive的安装 hive的数据类型 基本命令操作
一、hive产生背景
Apache Hive数据仓库软件可以使用SQL方便地阅读、编写和管理分布在分布式存储中的大型数据集。结构可以投射到已经存储的数据上。提供了一个命令行工具和JDBC驱动程序来将用户连接到Hive。
-
由Facebook开源,最初用于解决海量结构化的日志数据统计问题
-
MapReduce编程的不便性
-
HDFS上的文件缺少Schema(字段名,字段类型等)
二、Hive是什么
-
构建在Hadoop之上的数据仓库
-
Hive定义了一种类SQL查询语言:HQL(类似SQL但不完全相同)
-
通常用于进行离线数据处理(采用MapReduce)
-
底层支持多种不同的执行引擎(Hive on MapReduce、Hive on Tez、Hive on Spark)
-
支持多种不同的压缩格式、存储格式以及自定义函数(压缩:GZIP、LZO、Snappy、BZIP2.. ; 存储:TextFile、SequenceFile、RCFile、ORC、Parquet ; UDF:自定义函数)
到底什么是Hive,我们先看看Hive官网Wiki是如何介绍Hive的(https://cwiki.apache.org/confluence/display/Hive/Home):
Apache HiveApache Hive™ 数据仓库软件为分布式存储的大数据集上的读、写、管理提供很大方便,同时还可以用SQL语法在大数据集上查询。
1、是一种易于对数据实现提取、转换、加载的工具(ETL)的工具。可以理解为数据清洗分析展现。2、它有一种将大量格式化数据强加上结构的机制。3、它可以分析处理直接存储在hdfs中的数据或者是别的数据存储系统中的数据,如hbase。4、查询的执行经由mapreduce完成。5、hive可以使用存储过程6、通过Apache YARN和Apache Slider实现亚秒级的查询检索。
(Slider简介https://blog.csdn.net/jiewuyou/article/details/42614073)
三、hive的安装
1.hive的单机安装(使用derby做元数据存储)
-
安装包准备
将hive安装包 apache-hive-1.2.1-bin.tar.gz 上传到虚拟机/bigdata/下
JDK安装包 jdk-8u151-x64.gz
集群的准备(min1,min2,min3)
-
hive的解压安装
将上传的hive解压缩至虚拟机/app目录下
tar -zxvf /app/apache-hive-1.2.1-bin.tar.gz -C /app
mv /app/apache-hive-1.2.1-bin/ /app/hive-1.2.1
-
配置hive的配置文件
查看配置文件内容
拷贝配置文件hive-env.sh.template为hive-env.sh
cp /app/hive-1.2.1/conf/hive-env.sh.template /app/hive-1.2.1/conf/hive-env.sh
vim /app/hive-1.2.1/conf/hive-env.sh
-
配置hive的环境变量
vim /etc/profile
source /etc/profile which hive
-
启动hadoop集群
启动hive服务
hive
-
查看数据库
show databases;
创建数据库
create database myhive; show databases;
创建表
create table student(id int,chinese string,math string,English string);
-
加载数据并查询
load data local inpath '/root/student.txt' into table student; select * from student;
2.hive的独立安装模式(使用mysql做元数据存储)
-
安装MySQL服务器端和MySQL客户端,并启动mysql服务。
-
在min1上为Hive建立相应的MySQL账户,并赋予足够的权限
create user 'hive' identified by '123456';
GRANT ALL PRIVILEGES ON *.* TO aaa@qq.com'%' IDENTIFIED BY '123456' with grant option;
GRANT ALL PRIVILEGES ON *.* TO aaa@qq.com'localhost' IDENTIFIED BY '123456' with grant option;
flush privileges
查看是否成功
-
在内嵌模式下继续配置hive:hive-site.xml,hive-env.sh
配置hive-env.sh
配置hive-site.xml,拷贝/app/hive-1.2.1/conf下的hive-default.xml文件为hive-site.xml
cp /app/hive-1.2.1/conf/hive-default.xml.template /app/hive-1.2.1/conf/hive-site.xml
vim /app/hive-1.2.1/conf/hive-site.xml
-
拷贝数据驱动jar包到指定目录/app/hive-1.2.1/lib/下。没有驱动包会报错
-
-
使用命令行的方式启动hive服务,然后查看数据库,创建数据库名为heihei,查看集群web页面
-
查看集群web页面,可以看见在hdfs上生成了对应heihei数据库的文件目录
-
使用beeline访问hive
exit命令退出刚才的hive服务,在min1上修改hadoop 配置文件 etc/hadoop/core-site.xml,加入如下配置项,通过httpfs接口匿名的方式登录到hdfs文件系统。然后重新启动集群。
<property> <name>hadoop.proxyuser.root.hosts</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.root.groups</name> <value>*</value> </property>
使用命令hive --service hiveserver2 & 后台启动hive服务
hive --service hiveserver2 &
克隆窗口作为客户端连接,执行beeline脚本
连接服务端,这种方式使用了thrift服务,10000为默认的连接端口号
!connect jdbc:hive2://min1:10000
验证连接的是不是我们刚才用命令行方式访问的hive服务
3.hive的远程安装模式
安装规划:
集群min1,min2,min3;使用min1作为hive服务端,min2作为客户端连接,min3提供mysql数据库存储元数据。
安装准备:
-
min1,min2安装hive,min3上安装mysql数据库。
-
min1,min2,min3三台机器搭建hadoop集群。
-
jdk版本1.7及以上。
安装步骤:
1.在min3上安装mysql数据库,可以使用yum安装或者上传安装包使用rpm命令安装
在安装好的数据上进行以下操作:
create user 'hive' identified by '123456';
GRANT ALL PRIVILEGES ON *.* TO aaa@qq.com'%' IDENTIFIED BY '123456' with grant option;
GRANT ALL PRIVILEGES ON *.* TO aaa@qq.com'localhost' IDENTIFIED BY '123456' with grant option;
flush privileges
2、选节点min1作为hive的服务端,hive-env.sh配置与前两种安装方式一样。以下为hive-site.xml的配置
vim /app/hive-1.2.1/conf/hive/hive-site.xml
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/multiuserhive/warehouse</value>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://linux3:3306/hive?createDatabaseIfNotExist=true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
</property>
注意:作为服务端需要连接mysql,所以需要将mysql的驱动包拷贝到hive的lib目录下:
3、选择服务器min2作为hive客户端,并将配置好的服务端的hive目录拷贝到该节点上
vim /app/hive-1.2.1/conf/hive/hive-site.xml
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/multiuserhive/warehouse</value>
</property>
<!--配置是否在本地开启memstore服务-->
<property>
<name>hive.metastore.local</name>
<value>false</value>
</property>
<!--配置元数据服务的url-->
<property>
<name>hive.metastore.uris</name>
<value>thrift://linux1:9083</value> <!--linux1是hive服务器的ip-->
</property>
4、启动多用户的hive:
-
hive --service metastore (该启动非后台启动,退出后客户端就连接不上)
后台启动metastore: hive --service metastore &
-
在客户端linux2上连接hive服务:hive
四、hive的列的分割符
四、hive的数据类型
1.基本数据类型
类型 | 描述 | 示例 |
---|---|---|
TINYINT | 1字节 有符号整数 | 1 |
SMALLINT | 2字节 有符号整数 | 1 |
INT | 4字节 有符号整数 | 1 |
BIGINT | 8字节 有符号整数 | 1 |
FLOAT | 4字节 单精度浮点数 | 1.0 |
DOUBLE | 8字节 双精度浮点数 | 1.0 |
BOOLEAN | true/false | TRUE |
STRING | 字符串 | ‘a’,”a” |
BINARY | 字节数组 | |
TIMESTAMP | 精度到纳秒的时间戳 | 132550245000,‘2016-01-01 03:04:05.123456789' |
新增数据类型TIMESTAMP的值可以是:
-
整数:距离Unix新纪元时间(1970年1月1日,午夜12点)的秒数
-
浮点数:距离Unix新纪元时间的秒数,精确到纳秒(小数点后保留9位数)
-
字符串:JDBC所约定的时间字符串格式,格式为:YYYY-MM-DD hh:mm:ss:fffffffff
BINARY数据类型用于存储变长的二进制数据。
2.复杂数据类型
类型 | 描述 | 示例 |
---|---|---|
ARRAY | 一组有序字段,字段的类型必须相同 | array(1,2) |
MAP | 一组无需的键值对,键的类型必须是原子的,值可以是任何类型。同一个映射的键的类型必须相同,值的类型也必须相同。 | map(‘a’,1,’b’,2) |
STRUCT | 一组命名的字段,字段的类型可以不同 | struct(‘a’,1,1,0) |
3.数据类型应用举例
##创建员工表,使用默认分割符
CREATE TABLE employee(
name STRING,
salary FLOAT,
leader ARRAY<STRING>,
deductions MAP<STRING,FLOAT>,
address STRUCT<street:STRING,city:STRING,state:STRING,zip:INT>
)
;
4.列的分割符
HiveQL文本文件数据编码表
类型 | 描述 |
---|---|
\n | 对于文本文件来说,每行都是一条记录,因此换行符可以分割记录 |
^A(Ctrl+A) | 用于分隔字段(列)。在CREATE TABLE语句中可以使用八进制编码\001表示 |
^B | 用于分隔ARRARY或者STRUCT中的元素,或用于MAP中键-值对之间的分隔。在CREATE TABLE语句中可以使用八进制编码\002表示 |
^C | 用于MAP中键和值之间的分隔。在CREATE TABLE语句中可以使用八进制编码\003表示 |
CREATE TABLE employee(
name STRING,
salary FLOAT,
subordinates ARRAY<STRING>,
deductions MAP<STRING,FLOAT>,
address STRUCT<street:STRING,city:STRING,state:STRING,zip:INT>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\001'
COLLECTION ITEMS TERMINATED BY '\002'
MAP KEYS TERMINATED BY '\003'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
-
[ROW FORMAT DELIMITED]关键字,是用来设置创建的表在加载数据的时候,支持的列分隔符;
-
FIELDS TERMINATED BY '\001' ,字符\001是^A的八进制数。这个子句表明Hive将使用^A字符作为列分隔符。
-
COLLECTION ITEMS TERMINATED BY '\002' ,字符\002是^B的八进制数。这个子句表明Hive将使用^B字符作为集合元素的分隔符。
-
MAP KEYS TERMINATED BY '\003' ,字符\003是^C的八进制数。这个子句表明Hive将使用^C字符作为map的键和值之间的分隔符。
-
LINES TERMINATED BY '\n' 、STORED AS TEXTFILE这个两个子句不需要ROW FORMAT DELIMITED 关键字
-
Hive目前对于LINES TERMINATED BY…仅支持字符‘\n’,行与行之间的分隔符只能为‘\n’。
五、hive的基本命令
1.数据库的创建:
本质上是在hdfs上创建一个目录,使用comment加入数据库的描述信息,描述信息放在引号里。数据库的属性信息放在描述信息之后用with dbproperties 加入,属性信息放在括号内,属性名和属性值放在引号里,用等号连接有多条属性用逗号分隔
##创建一个数据库名为myhive,加入描述信息及属性信息
create database myhive comment 'this is myhive db'
with dbproperties ('author'='me','date'='2018-4-21')
;
##查看属性信息
describe database extended myhive;
##在原有数据库基础上加入新的属性信息
alter database myhive set dbproperties ('id'='1');
##切换库
use myhive;
##删除数据库
drop database myhive;
2.表的创建
默认创建到当前数据库(default是hive默认库),创建表的本质也是在hdfs上创建一个目录
==================练习array的使用,本地数据加载,对比hive与mysql的区别========================
##创建数据array.txt映射表t_array
create table if not exists t_array(
id int comment 'this is id',
score array<tinyint>
)
comment 'this is my table'
row format delimited fields terminated by ','
collection items terminated by '|'
tblproperties ('id'='11','author'='me')
;
##从本地加载数据array.txt文件
load data local inpath '/testdata/array.txt' into table t_array;
##查询表里面的数据
select * from t_array;
##查询id=1的第一条成绩信息
select score[0] from t_array where id=1;
##查询id=2的成绩条数
select size(score) from t_array where id=2;
##查询一共有多少条数据
select count(*) from t_array;
##把arra1.txt追加的方式从本地加载进这个表中
load data local inpath '/testdata/array1.txt' into table t_array;
##把test.txt追加的方式从本地加载进这个表中
load data local inpath '/testdata/test.txt' into table t_array;
##从本地覆盖方式加载数据array.txt文件至t_array表中
load data local inpath '/testdata/array.txt' overwrite into table t_array;
====================练习map的使用,查看表的创建过程,创建表的同时指定数据位置===================
##创建数据map.txt的映射表t_map
create table if not exists t_map(
id int,
score map<string,int>
)
row format delimited fields terminated by ','
collection items terminated by '|'
map keys terminated by ':'
stored as textfile
;
##从hdfs加载数据,map.txt在hdfs上的位置位置被移动。
load data local inpath '/testdata/map.txt' into table t_map;
##查询id=1的数学成绩
select score['math'] from t_map where id=1;
##查询每个人考了多少科
select size(score) from t_map;
##查看表的创建过程
show create table t_map;
CREATE TABLE `t_map1`(
`id` int,
`score` map<string,int>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '|'
MAP KEYS TERMINATED BY ':'
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
'hdfs://linux5:8020/user/hive/warehouse/t_map'
;
##创建表的同时指定数据的位置
create table if not exists t_map2(
id int,
score map<string,int>
)
row format delimited fields terminated by ','
collection items terminated by '|'
map keys terminated by ':'
stored as textfile
location '/test'
;
##删除表
drop table test2;
====================练习struct的使用,外部表的创建,总结内部表外部表的区别=====================
##创建数据struct.txt的映射表t_struct(使用external关键字并指定数据位置创建外部表)
create external table if not exists t_struct(
id int,
grade struct<score:int,desc:string,point:string>
)
row format delimited fields terminated by ','
collection items terminated by '|'
location '/external'
##查看score>90的信息
select * from t_struct where grade.score>90;
##创建外部表t_struct1
create external table if not exists t_struct1(
id int,
grade struct<score:int,desc:string,point:string>
)
row format delimited fields terminated by ','
collection items terminated by '|'
;
##insert into 方式追加数据
insert into table t_struct1 select * from t_struct;
##删除表:只有元数据被删除,数据文件仍然存储在hdfs上
drop table t_struct;
3.为hive表加载数据:
将数据文件copy到对应的表目录下面(如果是hdfs上的目录,将是剪切)。
##load方式从本地加载数据,会将数据拷贝到表所对应的hdfs目录
#追加
load data local inpath '本地数据路径' into table tablename
#覆盖
load data local inpath '本地数据路径' overwrite into table tablename
##load方式从hdfs加载数据,会将数据移动到对应的hdfs目录
#追加
load data inpath 'hdfs数据路径' into table tablename
#覆盖
load data inpath 'hdfs数据路径' into table tablename
##通过查询语句向表中插入数据
#追加
insert into table table1 select * from table2
#覆盖
insert overwrite into table table1 select * from table2
4.内部表与外部表
内部表:在Hive 中创建表时,默认情况下Hive 负责管理数据。即,Hive 把数据移入它的"仓库目录" (warehouse directory)
外部表:由用户来控制数据的创建和删除。外部数据的位置需要在创建表的时候指明。使用EXTERNAL 关键字以后, Hìve 知道数据并不由自己管理,因此不会把数据移到自己的仓库目录。事实上,在定义时,它甚至不会检查这一外部位置是否存在。这是一个非常重要的特性,因为这意味着你可以把创建数据推迟到创建表之后才进行。
区别:丢弃内部表时,这个表(包括它的元数据和数据)会被一起删除。丢弃外部表时,Hive 不会碰数据,只会删除元数据,而不会删除数据文件本身
5.表属性修改
##创建表log2
CREATE external TABLE log2(
id string COMMENT 'this is id column',
phonenumber bigint,
mac string,
ip string,
url string,
status1 string,
status2 string,
up int,
down int,
code int,
dt String
)
COMMENT 'this is log table' ##加入描述信息
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' '
LINES TERMINATED BY '\n'
stored as textfile;
##加载数据
load local data inpath '/home/data.log.txt' into table log2;
修改表名:rename to
alter table原名rename to 新名
alter table log rename to log2;
修改列名:change column
alter table 表名 change column 字段名 新字段名 字段类型【描述信息】;
##修改列名
alter table log4 change column ip myip String;
##修改列名同时加入列的描述
alter table log4 change column myip ip String comment 'this is mysip' ;
##使用after关键字,将修改后的字段放在某个字段后
alter table log4 change column myip ip String comment 'this is myip' after code;
##使用first关键字。将修改的字段调整到第一个字段
alter table log4 change column ip myip int comment 'this is myip' first;
添加列:add columns
##添加列,使用add columns,后面跟括号,括号里面加要加入的字段及字段描述,多个字段用逗号分开
alter table log4 add columns(
x int comment 'this x',
y int
);
删除列:
##删除列,使用replace columns,后面跟括号,括号里面加要删除的字段,多个字段用逗号分开
alter table log4 replace columns(x int,y int);
alter table log4 replace columns(
myip int,
id string,
phonenumber bigint,
mac string,
url string,
status1 string,
status2 string,
up int,
down int,
code int,
dt string
);
将内部表转换为外部表:
alter table log4 set tblproperties(
'EXTERNAL' = 'TRUE'
);
alter table log4 set tblproperties(
'EXTERNAL' = 'false'
);
alter table log4 set tblproperties(
'EXTERNAL' = 'FALSE'
);