前言
之前的文章中介绍了关于Hive的环境安装内容,这一节主要是记录一些关于Hive的实操记录。
下边我将通过一个简单的学生-老师-课程-得分的案例进行讲解,关于HQL的简单实践。Hive实践的sql其实大部分语法可以从MySQL进行横向迁移过来,所以入门难度整体较低。这里主要是一些简单的SQL梳理。
创建表SQL
sql
DROP TABLE IF EXISTS student_info;
create table if not exists student_info
(
stu_id string ,
stu_name string ,
birthday string ,
sex string
)
row format delimited fields terminated by ','
stored as textfile;
DROP TABLE IF EXISTS course_info;
create table if not exists course_info
(
course_id string ,
course_name string ,
tea_id string
)
row format delimited fields terminated by ','
stored as textfile;
DROP TABLE IF EXISTS teacher_info;
create table if not exists teacher_info
(
tea_id string ,
tea_name string
)
row format delimited fields terminated by ','
stored as textfile;
DROP TABLE IF EXISTS score_info;
create table if not exists score_info
(
stu_id string ,
course_id string ,
score int
)
row format delimited fields terminated by ','
stored as textfile;
创建好基础的表之后,可以通过本地指定txt文件进行数据写入。
shell
load data local inpath '/Users/linhao/env/tmp/hive-source-data/student_info.txt' into table student_info;
load data local inpath '/Users/linhao/env/tmp/hive-source-data/score_info.txt' into table score_info;
load data local inpath '/Users/linhao/env/tmp/hive-source-data/teacher_info.txt' into table teacher_info;
load data local inpath '/Users/linhao/env/tmp/hive-source-data/course_info.txt' into table course_info;
可能第一次接触的朋友不是很清楚这些txt文件的内容格式,这里我给出一份示例:
shell
> cat /Users/linhao/env/tmp/hive-source-data/student_info.txt
1,成小王,2002-10-01,男
2,张筱春,2004-01-01,女
3,杜小娟,2004-02-21,女
4,成大名,2001-01-01,男
5,望京西,2003-02-02,男
> cat /Users/linhao/env/tmp/hive-source-data/score_info.txt
1,1,94
2,2,88
1,2,45
2,1,66
> cat /Users/linhao/env/tmp/hive-source-data/teacher_info.txt
1001,张沛东
1002,李晓
1003,高田文
1004,高丽松
> cat /Users/linhao/env/tmp/hive-source-data/course_info.txt
1,语文,1002
2,数学,1003
3,英语,1004
由于建表的时候,使用了textfile作为存储类型,并且使用逗号作为列分隔标识,所以原始数据也需要使用txt文件存储,而且利用逗号进行数据拆分。
数据写入的方式有哪些
其实hive的数据写入方式有很多种,这里我整理了下常用的写入方式方便大家了解:
insert直接插入
这种方式最直接了当,除了我这里介绍的insert以外,还有一种overwrite的用法,那种属于覆盖写。
sql
insert into [tablename] values (val1,val2,val3);
select后直接insert插入
这种方式一般是用于从A表迁移数据到B表,也可以用于两张存储类型不同的表之间的数据拷贝,例如从text存储模式的表数据,复制到orc存储模式的表中。**
**
sql
insert into [dest_table] select col1,col2,col3... from [source_table] where [condition]
从指定文件加载进hive中
这种方式我们上文有用到,不过是用了本地磁盘路径进行导入,这里也可以支持使用hdfs上指定文件的数据导入。
sql
load data [local] inpath 'local path / hdfs path' [overwrite] into table [tablename]
数据查询
在前边初始化完成数据后,可以简单的尝试一些SQL查询的练习。这里我提供一些简单的demo供大家测试使用。
查询学生对应的课程的分数是多少
sql
select si.stu_id,si.stu_name,sc.score,ci.course_id,ci.course_name from score_info as sc left join student_info si on sc.stu_id=si.stu_idleft join course_info ci on ci.course_id=sc.course_id
查询不及格的学生有哪些
sql
select si.stu_id,si.stu_name,sc.score,ci.course_id,ci.course_name from score_info as sc left join student_info si on sc.stu_id=si.stu_idleft join course_info ci on ci.course_id=sc.course_idwhere sc.score<60
查询各个科目的最高分
sql
select course_id,max(score) from score_info group by (course_id)
使用case when将得分表展示得更友好一些
sql
select stu_id,score, case when score<60 then '不及格' when score>=60 and score<80 then '及格'when score>=80 and score<90 then '良好'when score>=90 then '优秀' end from score_info;
Hive的存储文件格式
Apache Hive支持Apache Hadoop中使用的几种熟悉的文件格式,如 TextFile(文本格式),RCFile(行列式文件),SequenceFile(二进制序列化文件),AVRO,ORC(优化的行列式文件)和Parquet 格式,而这其中我们目前使用最多的是TextFile,SequenceFile,ORC和Parquet。
关于存储文件格式这块所涉及的内容较多,因此不在本文中进行提及,这里只做简单介绍。
以下是一些使用不同存储格式的建表SQL示例:
使用ORC文件格式建表:
lua
DROP TABLE IF EXISTS student_info_orc;
create table if not exists student_info_orc
(
stu_id string ,
stu_name string ,
birthday string ,
sex string
)
row format delimited fields terminated by ';'
stored as orc;
默认orc存储会对数据进行压缩处理,如果你希望关闭压缩这一步骤的话(一般不推荐使用),其实可以通过开关进行设置
sql
create table if not exists student_info_orc
(
stu_id string ,
stu_name string ,
birthday string ,
sex string
)
row format delimited fields terminated by ';'
stored as orc tblproperties ("orc.compress"="SNAPPY");
使用Parquet文件格式建表:
lua
DROP TABLE IF EXISTS student_info_par;
create table if not exists student_info_par
(
stu_id string ,
stu_name string ,
birthday string ,
sex string
)
row format delimited fields terminated by ';'
stored as parquet;
数据分区
一般企业中使用Hive存储的时候都会设置相关的分区字段,相关HQL示例如下:
sql
create table day_table(
id int,
content string,
imp_date string
)
partitioned by (imp_date string);
ps:注意分区的字段不能在表定义里面存在,否则会报错。
如果你需要插入数据的话,可以利用以下SQL进行写入:
sql
insert into day_table values (11,'content is here','20241019');insert into day_table values (11,'content is here','20241020');insert into day_table values (11,'content is here','20241021');
查询分区的数据:
csharp
select * from day_table where imp_date='20241019'
查看分区存储情况:
bash
hdfs dfs -ls /user/hive/warehouse/test_db.db/day_table/
你会看到hdfs的存储的root路径,然后可以将不同分区的数据下载到本地进行查看。其实所谓的分区不过是在hdfs的根目录下按照不同的分区名称创建不同的子目录进行数据存储而已。
你也可以尝试将指定分区的数据下载的本地进行查看:
ini
hdfs dfs -get /user/hive/warehouse/test_db.db/day_table/imp_date=20241019/000000_0
这里因为我是用了textfile的格式进行数据存储,因此下载到本地后就是易读的txt格式,比较好理解。