已复制
全屏展示
复制代码

Hive 快速入门


· 7 min read

一. 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/warehouseambari/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';
🔗

文章推荐