Hive 快速入门
一. hive执行流程
HiveQL 通过命令行或者客户端提交,经过 Compiler 编译器,运用 MetaStore 中的元数 据进行类型检测和语法分析,生成一个逻辑方案(Logical Plan),然后通过优化处理,产生一个 MapReduce 任务。
Hive的存储结构包括数据库、表、视图、分区。数据库、表、分区都对应 HDFS 上的目录,而数据对应 HDFS 对应目录下的文件。Hive 中所有的数据都存储在 HDFS 中,没有专门的数据存储格式,Hive 是读模式的数据库,可支持 TextFile,SequenceFile,RCFile
或者自定义格式等。
只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据:
- Hive 的默认列分隔符:控制符 ^A(Ctrl + A),在CREATE TABLE语句中可以使用八进制编码\001表示。
- Hive 的默认行分隔符:换行符 \n。
Hive 中包含以下数据模型:
database
:在 HDFS 中表现为${hive.metastore.warehouse.dir}
目录下一个文件夹table
:在 HDFS 中表现所属 database 目录下一个文件夹external table
:与 table 类似, 外部表存放目录${hive.metastore.warehouse.dir}
,或者指定目录。partition
:在 HDFS 中表现为 table 目录下的子目录。bucket
:在 HDFS 中表现为同一个表目录或者分区目录下根据某个字段的值进行hash
散列之后的多个文件。view
:与传统数据库类似,只读,基于基本表创建。
二. hive登录
beeline
直接回车,输入用户名和密码,默认情况下hive用户密码为空,这里输入的用户名所有拥有的权限也就是:最终能对hdfs进行读写的用户权限。
$ beeline
Enter username for jdbc:hive2://vn12:2181/default: hive
Enter password for jdbc:hive2://vn12:2181/default:
20/11/23 15:06:15 [main]: INFO jdbc.HiveConnection: Connected to vn12:10000
Connected to: Apache Hive (version 3.1.0.3.1.4.0-315)
Driver: Hive JDBC (version 3.1.0.3.1.4.0-315)
Transaction isolation: TRANSACTION_REPEATABLE_READ
Beeline version 3.1.0.3.1.4.0-315 by Apache Hive
0: jdbc:hive2://vn12:2181/default>
三. 内部表
表的元数据和数据都由Hive维护,创建表时会自动在HDFS的/user/hive/warehouse
(ambari
在/warehouse/tablespace/managed/hive
目录)目录下创建与表同名的文件夹,删除表时HDFS上的数据和文件夹会删除
CREATE TABLE IF NOT EXISTS person (
id int COMMENT '编号',
name string COMMENT '姓名'
)
COMMENT '人员表'
row format delimited fields terminated by '|';
四. 外部表
外部表就是创建一个映射关系,告诉hive在hdfs上的数据存储的字段格式,以便hive能够解析。删除表时只删除元数据,HDFS上的数据和文件夹保留,创建表时如果指定了HDFS的路径,则数据文件会直接存在指定路径下;如果创建表时不指定HDFS路径,会默认在/user/hive/warehouse
目录创建表文件夹(ambari
在/warehouse/tablespace/external/hive
目录)。其实,外部表只是一个映射关系而已,外部表通常只用来做查询操作,不会插入数据,只有hdfs的目录变化以后才会使用msck repair
工具更新hive的元数据信息。
4.1 外部表使用方法
# 创建一个外部数据库,会自动创建/warehouse/tablespace/external/hive/company.db目录
create database company;
use company;
# 创建person表,会自动创建/warehouse/tablespace/external/hive/company.db/person目录
CREATE EXTERNAL TABLE IF NOT EXISTS person(
id int COMMENT '编号',
name string COMMENT '姓名'
)
COMMENT '人员表'
row format delimited fields terminated by '|';
# 插入数据,会自动生成/warehouse/tablespace/external/hive/company.db/person/000000_0文件
insert into person(id, name) values(1,'yzy好');
# 文件的内容为
hadoop fs -cat /warehouse/tablespace/external/hive/company.db/person/000000_0
1|yzy好
4.2 外部表场景举例
在hdfs上有很多的文本数据,数据是格式化好的,每行使用"|"分隔,现在想使用hive 的外部表映射到 hdfs 的这些数据,从 hive 里面查询 hdfs 的数据。
# 现在有文本x.txt
cat x.txt
3|余子越|25
4|余子好|26
# 创建hdfs目录,并上传数据
hadoop fs -mkdir -p /user/work/hivedata/day=20191119/hour=16
hadoop fs -put x.txt /user/work/hivedata/day=20191119/hour=16/
# 创建hive的外部表,外部表有三个字段。该表使用day和hour来分区,即在hdfs上呈现的是不同的目录,并且指定了数据位置。
CREATE EXTERNAL TABLE student (
id INT,
name STRING,
age INT
)
PARTITIONED BY (day STRING, hour STRING)
row format delimited fields terminated by '|'
STORED AS textfile
LOCATION '/user/work/hivedata/';
# 创建好了以后查询
select * from student;
+-------------+---------------+--------------+--------------+---------------+
| student.id | student.name | student.age | student.day | student.hour |
+-------------+---------------+--------------+--------------+---------------+
| 3 | 余子越 | 25 | 20191119 | 16 |
| 4 | 余子好 | 26 | 20191119 | 16 |
+-------------+---------------+--------------+--------------+---------------+
# 准备另外的数据y.txt
cat y.txt
3|张子越|25
4|张子好|26
# 放在不同的hdfs目录
hadoop fs -mkdir -p /user/work/hivedata/day=20191119/hour=17
hadoop fs -put y.txt /user/work/hivedata/day=20191119/hour=17/
# 在hive上更新分区消息,然后查询新加入的数据
msck repair table student sync partitions;
select * from student;
+-------------+---------------+--------------+--------------+---------------+
| student.id | student.name | student.age | student.day | student.hour |
+-------------+---------------+--------------+--------------+---------------+
| 3 | 余子越 | 25 | 20191119 | 16 |
| 4 | 余子好 | 26 | 20191119 | 16 |
| 3 | 张子越 | 25 | 20191119 | 17 |
| 4 | 张子好 | 26 | 20191119 | 17 |
+-------------+---------------+--------------+--------------+---------------+
select * from student where hour=17;
+-------------+---------------+--------------+--------------+---------------+
| student.id | student.name | student.age | student.day | student.hour |
+-------------+---------------+--------------+--------------+---------------+
| 3 | 张子越 | 25 | 20191119 | 17 |
| 4 | 张子好 | 26 | 20191119 | 17 |
+-------------+---------------+--------------+--------------+---------------+
# 插入数据,外部表通常不推荐插入操作,外部表只用作查询。
insert into student partition(day="20191119", hour='16') values(5, "xyz", 44);
五. 分区表
hive为了将不同特征的数据存在不同hdfs目录下,引入了分区的概念,查询时指定不同的分区来减少查询压力。
create database company;
use company;
-- 创建表
create external table emp(
name string,
age int
)
partitioned by (provice string,city string);
-- 查看表的分区信息
show partitions company.emp
-- 插入数据
insert into emp partition(provice="hebei", city="baoding") values("tom",22);
用partitioned by
指定创建的分区,多个分区意味着多级目录。
六. 分桶表
CLUSTERED BY
来指定划分桶所用列和划分桶的个数。HIVE
对key的hash值除bucket个数取余数,保证数据均匀随机分布在所有bucket
里。SORTED BY
对桶中的一个或多个列另外排序- 其实桶的概念就是
MapReduce
的分区的概念,两者完全相同。物理上每个桶就是目录里的一个文件,一个作业产生的桶(输出文件)数量和reduce任务个数相同。
create table teacher (id int, name string)
clustered by (id)
sorted by (id asc) into 3 buckets;
七. 临时表
临时表的数据和元数据都由Hive
维护,只对当前Session
有效,Session
退出时表自动删除;
CREATE TEMPORARY TABLE IF NOT EXISTS person_tmp
(id int COMMENT '编号',name string COMMENT '姓名')
COMMENT '人员临时表'
STORED AS TEXTFILE
LOCATION '/user/hdfs/';
八. 建表语句常见语法
8.1 分隔符设定
ROW FORMAT DELIMITED 分隔符设置开始语句
FIELDS TERMINATED BY:设置字段与字段之间的分隔符
COLLECTION ITEMS TERMINATED BY:设置一个复杂类型(array,struct)字段的各个item之间的分隔符
MAP KEYS TERMINATED BY:设置一个复杂类型(Map)字段的key value之间的分隔符
LINES TERMINATED BY:设置行与行之间的分隔符
row format delimited
fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':'
lines terminated by '\n';