1. 程式人生 > >第二十一天 -- hive補充 -- hive分割槽、分桶 -- hive資料匯入匯出

第二十一天 -- hive補充 -- hive分割槽、分桶 -- hive資料匯入匯出

第二十一天 – hive補充 – hive分割槽、分桶 – hive資料匯入匯出

一、Hive基礎補充

使用的表及表資料

  1. dept

    CREATE TABLE dept(
      deptno int, 
      dname string, 
      loc string)
    ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' 
    STORED AS textfile;
    
    10,ACCOUNTING,NEW YORK
    20,RESEARCH,DALLAS
    30,SALES,CHICAGO
    40,OPERATIONS,BOSTON
    
  2. emp

    CREATE TABLE emp(
      empno int, 
      ename string, 
      job string, 
      mgr int, 
      hiredate string, 
      sal int, 
      comm int, 
      deptno int)
    ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' 
    STORED AS textfile
    
    7369,SMITH,CLERK,7902,1980-12-17,800,null,20
    7499,ALLEN,SALESMAN,7698,1981-02-20,1600,300,30
    7521,WARD,SALESMAN,7698,1981-02-22,1250,500,30
    7566,JONES,MANAGER,7839,1981-04-02,2975,null,20
    7654,MARTIN,SALESMAN,7698,1981-09-28,1250,1400,30
    7698,BLAKE,MANAGER,7839,1981-05-01,2850,null,30
    7782,CLARK,MANAGER,7839,1981-06-09,2450,null,10
    7788,SCOTT,ANALYST,7566,1987-04-19,3000,null,20
    7839,KING,PRESIDENT,null,1981-11-17,5000,null,10
    7844,TURNER,SALESMAN,7698,1981-09-08,1500,0,30
    7876,ADAMS,CLERK,7788,1987-05-23,1100,null,20
    7900,JAMES,CLERK,7698,1981-12-03,950,null,30
    7902,FORD,ANALYST,7566,1981-12-02,3000,null,20
    7934,MILLER,CLERK,7782,1982-01-23,1300,null,10
    
  • left join 、left outer join 、left semi join:以左表為準連線右表,如果右表連線不上將null替代
select
e1.ename
from emp e
left join emp e1
on e.mgr = e1.empno 
where e.ename = "JONES"
;

select
e1.ename
from emp e
left outer join emp e1
on e.mgr = e1.empno 
where e.ename = 'JONES'
;

=======
select
d.*
from dept d
left semi join emp e
on e.deptno = d.deptno and e.deptno is null
;

select
d.*
from dept d
left semi join emp e
on e.deptno = d.deptno 
where e.deptno is null
;
  • right join 、right outer join:右連線,以右表準,連線左表,如果左表連線不上用null替代
    hive不支援右半開連線,即不支援right semi join
select
e1.ename
from emp e
right join emp e1
on e.mgr = e1.empno 
where e.ename = 'JONES'
;
  • 多表用"," 、 join 、 inner join:內連線,兩張表能相互關聯即可
select
e1.ename
from emp e
inner join emp e1
on e.mgr = e1.empno 
where e.ename = 'JONES'
;

select
e1.ename
from emp e,emp e1
where e.mgr = e1.empno and e.ename = 'JONES'
;
  • full join 、 full outer join : 全連線、全外連結

  • hive在1.2.2是預設開啟了使用map端join查詢;但是在hive的一些老版本中沒有預設開啟map-join,需要使用出MAPJOIN()來觸發執行mapjoin,MAPJOIN()雖然已經過時,但是也可以使用,

select
/*+MAPJOIN(d)*/
d.dname name,
max(e.sal) high_sal
from dept d
inner join emp e
on d.deptno = e.deptno
group by d.dname,e.deptno
;
  • 所有join的on只支援等值連線,on後可以有and,不支援<> != < > 等,永遠是小表(結果集)驅動大表(結果集),小表放左邊。

  • group by:分組,通常和聚合函式搭配使用
    select後面的欄位要麼在group by中出現過,要麼在聚合函式裡面。

  • having:對分完組之後的結果進行過濾,通常和group by搭配使用
    having後是可以用聚合函式,而where不行

  • order by:全域性排序,全域性即對所有的reducer進行排序,一般reducer只有一個。
    sort by :區域性排序,對每一個redcuer中的資料排序。當只有一個reducer的時候,sort by 和 order by一樣。
    預設用升序,asc,降序desc

  • distribute by:將map中的資料分到哪一個reduce中,預設也有。

  • cluster by:兼有distribute by 和 sort by的功能,既能能指定distribute by,也能sort by,但是sort by必須是升序。

select
sal sal
from emp
cluster by sal
;
==========以上等價於以下
select
sal
from emp
distribute by sal
sort by sal desc
;
  • union : 將一個或者多個結果集進行合併,該合併會排序去重。
    union all :量一個或者多個結果集進行合併,排序但不會去重。
select
d.deptno id,
d.dname name
from dept d
union
select
e.empno id,
e.ename name
from emp e
;

select
d.deptno id,
d.dname name
from dept d
union
select
d.deptno id,
d.dname name
from dept d
;
=================
select
d.deptno id,
d.dname name
from dept d
union all
select
d.deptno id,
d.dname name
from dept d
;

select
d.deptno id,
d.dname name
from dept d
union all
select
d.deptno id,
d.dname name
from dept d
limit 2
;

注意:
多個union的子集中的欄位個數、欄位的名稱(名稱不一樣的起別名)、欄位型別需要保持一致。
單個union子句不支援order by 、group by、distribute by等。
orderByClause clusterByClause distributeByClause sortByClause limitClause

二、Hive分割槽

hive分割槽的目的

hive為了避免全表掃描,從而引進分割槽技術來將資料進行劃分。減少不必要資料的掃描,從而提高效率。

hive分割槽和mysql分割槽的區別

mysql分割槽欄位用的是表內欄位;而hive分割槽欄位採用表外欄位。

hive的分割槽技術
  1. hive的分割槽欄位是一個偽欄位,但是可以用來進行操作。
  2. 分割槽欄位不進行區分大小寫
  3. 分割槽可以是表分割槽或者分割槽的分割槽,可以有多個分割槽
hive分割槽根據

看業務,只要是某個標識能把資料區分開來。比如:年、月、日、地域、性別等

分割槽關鍵字

partitioned by(欄位)

分割槽本質

在表的目錄或者是分割槽的目錄下在建立目錄,分割槽的目錄名為指定欄位=值

hive分割槽練習
create table if not exists u1(
id int,
name string,
age int
)
partitioned by(dt string)
row format delimited fields terminated by ' '
stored as textfile
;

u1

1 xm1 16
2 xm2 18
3 xm3 22

u2

11 xh1 26
22 xh2 28
33 xh3 30

匯入資料

load data local inpath ‘/home/userdata/u1’ into table u1 partition(dt=“2018-10-14”);
load data local inpath ‘/home/userdata/u115’ into table u1 partition(dt=“2018-10-15”);

載入資料後,在hdfs中檢視目錄

1540005178960

檢視分割槽

select * from u1 where dt=‘2018-10-15’;

1540005246913

hive分割槽練習2 – 二級分割槽
create table if not exists u2(
id int,
name string,
age int
)
partitioned by(month int,day int)
row format delimited fields terminated by ' '
stored as textfile
;

u1914

1 xm1 16
2 xm2 18

u1915

3 xm3 22

u11014

11 xh1 26

u11015

22 xh2 28
33 xh3 30

匯入資料

load data local inpath ‘/home/userdata/u1914’ into table u2 partition(month=9,day=14);
load data local inpath ‘/home/userdata/u1915’ into table u2 partition(month=9,day=15);
load data local inpath ‘/home/userdata/u11014’ into table u2 partition(month=10,day=14);
load data local inpath ‘/home/userdata/u11015’ into table u2 partition(month=10,day=15);

1540008177057

hive分割槽修改

查詢分割槽

show partitions u1;

增加分割槽

alter table u1 add partition(dt=“2018-10-16”);
alter table u1 add partition(dt=“2018-10-16”) partition(dt=“2018-10-17”);
alter table u1 add partition(dt=“2018-10-19”) location “/user/hive/warehouse/test.db/u1/dt=2018-10-16/”;

修改分割槽(手動修改元資料資訊)

alter table u1 partition(dt=“2018-10-16”) rename to partition(dt=“2018-10-26”);

修改已存在分割槽的路徑

alter table u1 partition(dt=“2018-10-19”) set location “hdfs://qianfeng/user/hive/warehouse/test.db/u1/dt=2018-10-14/”;

刪除分割槽

alter table u1 drop partition(dt=“2018-10-27”);
alter table u1 drop partition(dt=“2018-10-26”),partition(dt=“2018-10-19”);

三、hive動態分割槽

引數設定

hive.exec.dynamic.partition=true; 是否允許動態分割槽

hive.exec.dynamic.partition.mode=strict/nostrict; 動態區模式為嚴格模式

​ strict:嚴格模式,最少需要一個靜態分割槽列(需指定固定值)
​ nostrict:非嚴格模式,允許所有的分割槽欄位都為動態。

hive.exec.max.dynamic.partitions=1000; 允許最大的動態分割槽

hive.exec.max.dynamic.partitions.pernode=100; 單個節點允許最大分割槽

建立動態分割槽表

動態分割槽表的建立語句與靜態分割槽表相同,不同之處在與匯入資料,靜態分割槽表可以從本地檔案匯入,但是動態分割槽表需要使用from…insert into語句匯入。

create table if not exists u3(
id int,
name string,
age int
)
partitioned by(month int,day int)
row format delimited fields terminated by ' '
stored as textfile
;

匯入資料,將u2表中的資料載入到u3中:

from u2
insert into table u3 partition(month,day)
select id,name,age,month,day
;
混合分割槽
create table if not exists u4(
id int,
name string,
age int
)
partitioned by(month int,day int)
row format delimited fields terminated by ' '
stored as textfile
;

匯入資料

from u2
insert into table u4 partition(month=9,day)
select id,name,age,day
where month=9
;
hive的mr的執行模式

set hive.mapred.mode=strict/nostrict;

在嚴格模式下,有以下限制:

1、Cartesian Product.笛卡爾積,沒有任何where和on的連線查詢。
2、No partition being picked up for a query.對分割槽表查詢不帶分割槽欄位做過濾。
3、Orderby without limit.order by不帶limit
4、Comparing bigints and strings.
5、Comparing bigints and doubles.

如下不能執行

select
*
from u4
;

select
*
from u4 u
join u3 uu
;

select
*
from u4
order by id
;

四、hive分桶

分桶目的作用

更加細緻地劃分資料;對資料進行抽樣查詢,較為高效;可以使查詢效率提高

分桶原理關鍵字

分桶欄位是表內欄位,預設是對分桶的欄位進行hash值,然後再模於總的桶數,得到的值則是分割槽桶數。

bucket
clustered by(id) into 4 buckets

分桶的本質

在表目錄或者分割槽目錄中建立檔案。

分桶案例

分四個桶

create table if not exists u5(
id int,
name string,
age int
)
partitioned by(month int,day int)
clustered by(id) into 4 buckets
row format delimited fields terminated by ' '
stored as textfile
;

對分桶的資料不能使用load的方式載入資料,使用load方式載入不會報錯,但是沒有分桶的效果。

為分桶表新增資料,需要設定set hive.enforce.bucketing=true;

首先將資料新增到u2表中

1 xm1 16
2 xm2 18
3 xm3 22
4 xh4 20
5 xh5 22
6 xh6 23
7 xh7 25
8 xh8 28
9 xh9 32

load data local inpath ‘/home/userdata/bu’ into table u2 partition(month=9,day=10);

from u2
insert into table u5 partition(month=9,day=10)
select id,name,age 
where month = 9 
and day = 10
;

對分桶進行查詢:tablesample(bucket x out of y on id)

x:表示從哪個桶開始查詢
y:表示桶的總數,一般為桶的總數的倍數或者因子。
x不能大於y。

select * from u5 tablesample(bucket 1 out of 4 on id); 查詢到三條資料

select * from u5 tablesample(bucket 2 out of 4 on id);查詢到兩條資料

select * from u5 tablesample(bucket 1 out of 2 on id); 1 1+4/2=3 3+4/2=5 查詢到五條資料

select * from u5 tablesample(bucket 1 out of 8 on id) where age > 22; 查詢到一條資料

隨機查詢

select * from u5 order by rand() limit 3;

select * from u5 tablesample(3 rows);

select * from u5 tablesample(30 percent); 按表的百分比查詢

select * from u5 tablesample(3G);

select * from u5 tablesample(3K); B、k、M、G 按要查詢的資料大小查詢

分割槽與分桶的對比

分割槽使用表外的欄位,分桶使用表內欄位

分割槽可以使用load載入資料,而分桶就必須要使用insert into方式載入資料

分割槽常用;分桶少用

五、hive資料匯入匯出

hive資料匯入
  1. load從本地載入

  2. load從hdfs中載入

  3. insert into方式載入

  4. location指定

  5. like指定,克隆

    create table if not exists u7 like u6;
    alter table u8 add partition(month=9,day=10);
    create table if not exists u9 like u6 location “hdfs://qianfeng/user/hive/warehouse/gp1801.db/u6/month=9/day=10”;

  6. ctas語句指定(create table as)

  7. 手動將資料copy到表目錄

hive資料匯出
  1. insert into方式匯出
  2. insert overwrite local directory:匯出到本地某個目錄
  3. insert overwrite directory:匯出到hdfs某個目錄
insert overwrite local directory '/home/uesedata/out/00'
select id,name from u2;

insert overwrite local directory '/home/uesedata/out/01'
row format delimited fields terminated by ','
select id,name from u2;

insert overwrite directory 'hdfs://bigdata/out/01'
row format delimited fields terminated by ','
select id,name from u11;

匯出到檔案

hive -S -e “use gp1801;select * from u2” > /home/out/02/result