完整hive總結
hive建立一張表,跟已經存在的結構化的數據文件產生映射關系。映射成功后,就可以通過寫HQL來分析這個結構化的數據文件,避免了寫mr程序的麻煩。
數據庫:和hdfs中/user/hive/warehouse下的一個文件夾對應;
表:和數據庫文件夾下面的子文件夾/user/hive/warehouse/庫名.db/表名 對應;
表的數據位置目前不能隨便存放,一定要在指定的數據庫表的文件夾下面;
建立表的時候,需要指定分隔符,否則可能會映射不成功。建表的字段個數和字段類型,要跟結構化數據中的個數類型一致。
分區表字段不能夠在表中已經存在;
分區字段是一個虛擬的字段,不存放任何數據;
分區字段的數據來自于裝載分區表數據的時候指定的;
分區表的字段在hdfs上的效果就是在建立表的文件夾下面又創建了子文件夾;
建立分區表的目的把數據的劃分更加細致,減少了查詢時候全表掃描的成本,只需要按照指定的分區掃描數據并顯示結果即可;
分區表就是輔助查詢,縮小查詢范圍,加快數據的檢索速度。分桶表在創建之前需要開啟分桶功能;
分桶表創建時,分桶的字段必須是表中已經存在的字段,即要按照表中的哪個字段進行分開;
分桶表也是把表所映射的結構數據文件分成更細致的部分,但是更多的是用在join查詢提高效率之上,只需要把join的字段在各自表中進行分桶操作。
Hive之影評分析案例
現有三分數據,具體數據如下:
1.users.txt
- 數據格式(共有6040條數據)
3:M:25:15:55117
- 對應字段
用戶id | 性別 | 年齡 | 職業 | 郵政編碼 |
---|---|---|---|---|
user_id | gender | age | work | coding |
2. movies.txt
- 數據格式(共有3883條數據)
3:Grumpier Old Men (1995):Comedy|Romance
- 對應字段
電影id | 電影名字 | 電影類型 |
---|---|---|
movie_id | name | genres |
3. ratings.txt
- 數據格式(共有1000209條數據)
1:661:3:978392198
- 對應字段
用戶id | 電影id | 評分 | 評分時間戳 |
---|---|---|---|
user_id | movie_id | rating | times |
庫表映射實現
- 建庫
create database movie;
use movie;
- 創建t_user表并導入數據
create table t_user(
user_id bigint,
gender string,
age int,
work string,
code string
) row format delimited fields terminated by ':';
load data local inpath '/home/tarena/hivedata/users.txt' into table t_user;
- 創建t_movie表并導入數據
create table t_movie(
movie_id bigint,
name string,
genres string
) row format delimited fields terminated by ':';
load data local inpath '/home/tarena/hivedata/movies.txt' into table t_movie;
4.創建t_rating表并導入數據
create table t_rating(
user_id bigint,
movie_id bigint,
rating double,
times string
) row format delimited fields terminated by ':';
load data local inpath '/home/tarena/hivedata/ratings.txt' into table t_rating;
案例實現
1. 求被評分次數最多的10部電影,并給出評分次數(電影名,評分次數)
- 需求字段
1.1) 電影名:t_movie.name
1.2) 評分次數:t_rating.rating
- 思路
按照電影名進行分組統計,求出每部電影的評分次數并按照評分次數降序排序。 - 實現
create table result1 as
select b.name as name,count(b.name) as total from t_movie b
inner join t_rating c on b.movie_id=c.movie_id
group by b.name
order by total desc
2. 求movieid=2116這部電影各年齡的平均影評(年齡,影評分)
- 需求字段
1.1) 年齡:t_user.age
1.2) 影評分:t_rating.rating
- 思路
t_user
和t_rating
表進行聯合查詢,movie_id=2116
過濾條件,年齡分組 - 實現
create table result3 as
select a.age as age, avg(c.rating) as avgrate from t_user a
join t_rating c
on a.user_id=c.user_id
where c.movie_id=2116
group by a.age;
3.分別求男性,女性當中評分最高的10部電影(性別,電影名,影評分)
- 需求字段
1.1) 性別:t_user.gender
1.2) 電影名:t_movie.name
1.3) 影評分:t.rating.rating
- 思路
2.1) 三表聯合查詢
2.2) 按照性別過濾條件,電影名作為分組條件,影評分作為排序條件進行查詢 - 實現
3.1) 女性當中評分最高的10部電影
create table result2_F as
select 'F' as sex, b.name as name, avg(c.rating) as avgrate
from t_rating c join t_user a on c.user_id=a.user_id
join t_movie b on c.movie_id=b.movie_id
where a.gender='F'
group by b.name order by avgrate desc
limit 10;
3.2) 男性當中評分最高的10部電影
create table result2_M as
select 'M' as sex, b.name as name, avg(c.rating) as avgrate
from t_rating c join t_user a on c.user_id=a.user_id
join t_movie b on c.movie_id=b.movie_id
where a.gender='M'
group by b.name order by avgrate desc
limit 10;
4.求最喜歡看電影(影評次數最多)的那位女性評最高分的10部電影的平均影評分(電影編號,電影名,影評分)
- 需求字段
1.1) 電影編號:t_rating.movie_id
1.2) 電影名:t_movie.name
1.3) 影評分:t_rating.rating
- 思路
2.1) 先找出最喜歡看電影的那位女性
2.2) 根據2.1中的女性user_id作為where過濾條件,以看過的電影影評分rating作為排序條件進行排序,找出評分最高的10部電影
2.3) 求出2.2中10部電影的平均分 - 實現
3.1) 最喜歡看電影的女性(t_rating.user_id,次數)
create table result4_A as
select c.user_id,count(c.user_id) as total from t_rating c
join t_user a on c.user_id=a.user_id
where a.gender='F'
group by c.user_id order by total desc limit 1;
3.2) 找出那個女人評分最高的10部電影
create table result4_B as
select c.movie_id, c_rating as rating from t_rating c
where c.user_id=1150 order by rating desc limit 10;
3.3) 求出10部電影的平均分
select d.movie_id as movie_id, b.name as name, avg(c.rating)
from result4_B d join t_rating on d.movie_id=c.movie_id
join t_movie on c.movie_id=b.movie_id
group by d.movie_id, b.name;