Hive 核心知识点

8 篇文章 0 订阅
2 篇文章 0 订阅
本文介绍了如何初始化Hive Metastore,启动Hive及Hadoop,进行数据加载、表结构操作,创建分区表、视图,并演示了Flume日志处理与外部分区表的应用。涵盖了SQL查询、数据安全与数据分析等关键步骤。
摘要由CSDN通过智能技术生成
--初始化Hive的Metastore命令
bin/ schematool -dbType mysql -initSchema 

--hive启动
--1 bin/hive
--启动hive需要先启动hadoop
---先hiveserver2
--后 bin/beeline -u jdbc:hive2://localhost:10000
--关闭防火墙
systemctl stop firewalld.service
--hdfs文件授权
hadoop fs -chmod 777 /tmp/hadoop-yarn

--设置全部权限hdfs dfs -chmod -R 777 /tmp

--#查看历史命令
more ~/.hivehistory

SELECT  *
FROM    t2_bak;



--从本地导数据到hive
load data local inpath '/data/soft/hivedata/t2.data' into table t2_bak;
--查询数据
select * from t2_bak;
--添加一个字段
alter table t2_bak add columns (name string);
--创建一个表
create table t2(age int comment '年龄')comment '测试';
--显示表的详细信息
show create table t2;
--查看表的信息
desc t2;
--登录数据库
mysql -uroot -pAdmin@123
--创建数据库并且添加注释
create table t2(
    age int comment '年龄'
)comment '测试'
--直接这样是会产生中文乱码的,接下来我们解决乱码问题
--1、登录mysql数据库mysql -uroot -pAdmin@123
--2、use hive;
--3、show create table COLUMNS_V2; 
--4、show create table TABLE_PARAMS;
--5、alter table COLUMNS_V2 modify column COMMENT varchar(256) character set utf8;
--6、alter table TABLE_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;
--7、alter table PARTITION_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;
--8、lter table PARTITION_KEYS modify column PKEY_COMMENT varchar(4000) character set utf8;
--这样就修改了hive的编码了,修改为utf8


--创建一个多字段的的表,接下来我们就创建一个多字段的表t3

create table t3(
    id int comment 'ID',
    stu_name string comment 'name',
    stu_birthday date comment 'birthday',
    online boolean comment 'is online'
);

-- 创建一个表,表中的字段数据类型为,array的使用

create table stu(
    id int,
    name string,
    favors array<string>
)row format delimited
fields terminated by '\t'
collection items terminated by ','
lines terminated by '\n';

--Map的使用
--建表语句如下:指定scores字段类型为map格式 
--通过collection items terminated by ','指定了map中元素之间的分隔符 
--通过map keys terminated by ':'指定了key和value之间的分隔符

create table stu2(
    id int,
    name string,
    scores map<string,int>
)row format delimited
fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':'
lines terminated by '\n';

-- 查询所有学生的语文和数学成绩
select id,name,scores['chinese'],scores['math'] from stu2;

select id,name,scores['chinese'] as chinese,scores['math'] as math,scores['english'] as english from stu2;
-- 再来介绍最后一种复合类型struct,有点像java中的对象,举个例子说明一下, 
--某学校有2个实习生,zhangsan、lisi,每个实习生都有地址信息,一个是户籍地所在的城市,一个是公
-- 司所在的城市,
-- 我们来组织一下数据

create table stu3(
    id int,
    name string,
    address struct<home_addr:string,office_addr:string>
)row format delimited
fields terminated by '\t'
collection items terminated by ','
lines terminated by '\n';

-- 案例:
-- 复合数据类型的使用
create table student(
    id int comment 'id',
    name string comment 'name',
    favors array<string>,
    scores map<string,int>,
    address struct<home_addr:string,office_addr:string>
)row format delimited
fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':'
lines terminated by '\n';



--创建一个外部表
create external table external_table(
    key string
)location '/data/external';
--按照上面的分析,我们来创建一个分区表,使用partitioned by指定区分字段,分区字段的名称为dt,类
--型为string 
create table partition_1 ( 
id int, 
name string  
) partitioned by (dt string) 
row format delimited 
fields terminated by '\t'; 


--向分区表中加载数据
load data local inpath '/data/soft/hivedata/partition_1.data' overwrite into table partition_1 partition(dt='2021-10-27');
--当然我也可以手动在表中只创建分区
alter table partition_1 add partition (dt='2021-89-56')

--查看分区表有那些 
show partitions partition_1;
--删除分区(删除分区以后呢,表中的数据也会被删除,因为是内部表)
alter table partition_1 drop partition(dt='2020-01-02'); 
alter table partition_1 drop partition(dt='2021-10-27'); 
--需要创建多个分区
create table partition_2(
    id  int,
    name string
)partitioned by (year int,school string)
row format delimited
fields terminated by '\t';

--加载数据的时候数据只需要有创建表的时候的字段就行了,具体的分区的数据我们需要在加载数据时进行指定
load data local inpath '/data/soft/hivedata/partition_2.data' 
into table partition_2 partition (year='2021',school='english');

--查询分区的数据
-- hive中的分区相当于一个查询条件,直接在后面加上一个where即可
select * from partition_2;--全表扫描
select * from partition_2 where year=2020;--用到了一个分区
select * from partition_2 where year=2020 and school='xk';--用到了两个字段进行过滤

--外部分区表
--创建一个外部分区表
create external table ex_par(
    id int,
    name string
)partitioned by (dt string)
row format delimited
fields terminated by '\t'
location '/data/ex_par';

--加载数据
load data local inpath '/data/soft/hivedata/ex_par.data' into table ex_par partition (dt='2020-12-12');
--删除分区
alter table ex_par drop partition(dt='2020-12-12');

-- 如果数据已经上传上去了,但是查不到是因为没有在表中添加分区信息,(使用前面的alter table ex_par add partition 命令),这里需要通过location指定分区目录
alter table ex_par add partition(dt='2020-12-12') location '/data/ex_par/dt=2020-12-12';
--添加分区(绑定数据和分区之间的关系)


--桶表 对数据进行哈希取值,然后放到不同文件中存储,物理上,每个桶就是一个表里的一个文件
--创建 一个桶表,这个表是按照id进行分桶的,分成4个桶
create table bucket_tb(
    id int
)clustered by (id) into 4 buckets;

insert into tableselectfrom;

--在插入数据之前需要开启设置桶的操作,不然数据是无法分到不同的桶里面的,其实这里的分桶就是设置reduce任务的数量,最终结果中文件的数量和reduce任务数量是挂钩的
--设置 
set hive.enforce.bucketing =true--自动控制reduce的数据从而适配bucket的个数
--初始化一个表,用于向桶表中加载数据
create table b_source(id int); 

--向桶表中加载数据
insert into table bucket_tb select id from b_source;
insert into table bucket_tb select id from b_source where id =1;


--创建视图
create view v1 as select t3_new.id,t3_new.stu_name from t3_new;
--注意:视图在/user/hive/warehouse中是不存在的。因为它只是一个虚拟的表。 视图只是一张虚表


--综合案例
-- 需求:Flume按天把日志数据采集到HDFS中的对应目录中,使用SQL按天统计每天数据的相关指标 
--分析一下:
--Flume按天把日志数据保存到HDFS中的对应目录中 
--针对Flume的source可以使用execsource、channel可以使用基于文件的或者内存的,sink使用
--hdfssink,在hdfssink的path路径中需要使用%Y%m%d获取日期,将每天的日志数据采集到指定的hdfs
--目录中
--这个是我们在前面学习Flume的时候已经讲过的了,这个倒不难
--后面就是需要对按天采集的日志数据建表,由于这份数据可能会被多种计算引擎使用,所以建议使用外部
--表,这样就算我们不小心把表删了,数据也还是在的,不影响其他人使用,还有就是这份数据是按天分目
--录存储的,在实际工作中,离线计算的需求大部分都是按天计算的,所以在这里最好在表中增加日期这个
--分区字段,所以最终决定使用外部分区表。
--前面FLume采集数据的流程我们就不再演示了,在这我就直接使用之前我们使用hdfs落盘的数据了。 
--我们之前有一个案例是分类型,分目录,把多种类型的数据存储到不同的目录下
--目录结构是这样的,首先是按天,然后是按照类型
--创建表
create external table ex_par_more_type(
    log string
)partitioned by(dt string,d_type string)
row format delimited
fields terminated by '\t'
location '/moreType';
--添加分区
alter table ex_par_more_type add partition(dt='20211022',d_type='giftRecord') location '/moreType/20211022/giftRecord';
alter table ex_par_more_type add partition(dt='20211022',d_type='userInfo') location '/moreType/20211022/userInfo';
alter table ex_par_more_type add partition(dt='20211022',d_type='videoInfo') location '/moreType/20211022/videoInfo';


select * from ex_par_more_type where dt='20211022' and d_type='giftRecord';
select * from ex_par_more_type where dt='20211022' and d_type='userInfo';
select * from ex_par_more_type where dt='20211022' and d_type='giftRecord';

--创建视图
create view gift_record_view as select get_json_object(log,'$.send_id') send_id,
get_json_object(log,'$video_id') as video_id,get_json_object(log,'$.gold') as gold,
dt from ex_par_more_type where d_type='giftRecord';


create view user_info_view as select get_json_object(log,'$.uid') as uid,
get_json_object(log,'$.nickname') as nickname,get_json_object(log,'$.usign') as usign,
get_json_object(log,'$.sex') as sex,
dt from ex_par_more_type where d_type='userInfo';


create view video_info_view as select get_json_object(log,'$.id') as id,
get_json_object(log,'$.uid') as uid,
get_json_object(log,'$.lat') as lat,
get_json_object(log,'$.lnt') as lnt, 
dt from ex_par_more_type where d_type = 'videoInfo'; 


--查询视图
select *  from user_info_view where dt='20211022';
select *  from gift_record_view where dt='20211022';
select *  from video_info_view where dt='20211022';


--创建一个定时器进程调度
#!/bin/bash 
# 每天凌晨1点定时添加当天日期的分区 
if [ "a$1" = "a" ] 
then 
  dt=`date +%Y%m%d` 
else 
  dt=$1 
fi 
# 指定添加分区操作 
hive -e "
alter table ex_par_more_type add if not exists partition(dt='${dt}',d_type='giftRecord') location '/moreType/${dt}/giftRecord';
alter table ex_par_more_type add if not exists partition(dt='${dt}',d_type='userInfo') location '/moreType/${dt}/userInfo';
alter table ex_par_more_type add if not exists partition(dt='${dt}',d_type='videoInfo') location '/moreType/${dt}/videoInfo';
"
--显示分区
show partitions ex_par_more_type;
--删除分区
alter table ex_par_more_type drop partition(dt='20211022',d_type='giftRecord');
alter table ex_par_more_type drop partition(dt='20211022',d_type='userInfo');
alter table ex_par_more_type drop partition(dt='20211022',d_type='videoInfo');


alter table ex_par_more_type add if not exists partition(dt='20211022',d_type='giftRecord') location '/moreType/${dt}/giftRecord';

--这个脚本需要配置一个定时任务,每天凌晨1点执行,可以使用crontab
00 01 * * * root /bin/bash /data/soft/hivedata/addPartition.sh >> /data/soft/hivedata/addPartition.log



--我们的需求是这样,有一份学生的考试分数信息,语文、数学、英语这三门,需要计算出班级中单科排名
-- 前三名学生的姓名

create external table student_score(
    id int,
    name string,
    sub string,
    scores int
)row format delimited
fields terminated by '\t'
location '/data/student_score';

row_number,row_number
不能单独使用,在这里需要加上over()

--查询数据
select *,row_number() over() from student_score;
--在这里相当于给表里面的所有数据编了一个号,从1开始,但是对这些数据进行先分组,再对组内数据进行排序,再编号
-- 就需要在over函数内部添加partion by进行分组,添加order by进行排序,最终给生成的编号起了别名num
select *,row_number() over (partition by sub order by scores desc) as num from student_score;
--取前3名
select * from (select *,row_number() over (partition by sub order by scores desc) as num from student_score)
s WHERE s.num<=3;

--rank()
select *,rank() over (partition by sub order by scores desc) as num from student_score;

--dense_rank()
select *,dense_rank() over (partition by sub order by scores desc) as num from student_score;

--总结一下:
--row_number() over() 是正常排序 
--rank() over()是跳跃排序,有两个第一名时接下来就是第三名(在各个分组内) 
--dense_rank() over()是连续排序,有两个第一名时仍然跟着第二名(在各个分组内)
--列转行
create external table student_favors( 
name string, 
favor string 
)row format delimited 
fields terminated by '\t' 
location '/data/student_favors'; 


select * FROM  student_favors;
--对字段name进行分组,把favor转化为一个数组
SELECT name,collect_list(favor) as favor_list FROM student_favors GROUP BY name;

--然后再使用concat_ws把数组中的元素按照指定分隔符转成字符串 
-- 这样就实现了多行数据转为一列数据了
-- 执行行转列操作

SELECT name,concat_ws(',',collect_list(favor)) as favor_list FROM student_favors GROUP BY name;

SELECT name,concat_ws(',',collect_set(favor)) as favor_list FROM student_favors GROUP BY name;

--行转列
create external table student_favors_2( 
name string,   
favorlist string 
)row format delimited  
fields terminated by '\t' 
location '/data/student_favors_2'; 

--先使用split对favorlist字段进行切割
select split(favorlist,',') FROM student_favors_2;
-- 再使用explode对数据进行操作
select explode(split(favorlist,',')) from student_favors_2;


select name,favor_new from student_favors_2 lateral view
 explode(split(favorlist, ',')) table1 as favor_new ;

 select id,from t2_bak sort by id;

 --设置reduce任务数为2
 set mapreduce.job.reduces = 2; 

 --两者结合使用的时候distribute by必须要写在sort by之前


 select id from t2_bak distribute by id sort by id; 









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值