Hive總結2(分割槽+分桶+查詢)
Hive是一個數據倉庫 ,儲存的半結構化資料 文字。
Hive不支援:事務,不支援索引(但可以通過分桶實現快速的查詢,hash)
類似的分佈的nosql(Not Only Sql資料庫:hbase - Phoinex(鳳凰)
Hive的功能,就是做mapreduce。
分割槽:
就是在可控制的情況下,將資料放到不同的目錄下。
減小查詢的範圍。 並不能加快查詢的速度。還是要查詢所有隻是分了一個目錄。
Stud.txt > mary=cp 目錄下
分桶就是hash儲存。Id = > where id=S001
將資料根據hashcode值進行分開儲存
查詢時對id進行hash得出結果,就知道放到了那個檔案下, 提高查詢的速度。
用外部表的方式管理,保證元資料不會丟失。
1.分割槽
通過partition by(欄位名 欄位型別) - 分割槽最後會形成一個目錄。
分割槽的欄位,不在源資料中出現,但是表的一部分
1.1建立一個分割槽表
hive> create table stud01(
> id string,
> name string,
> age int
> )
> partitioned by (grade string)
> row format delimited
> fields terminated by '\t';
1.2匯入資料
在匯入資料時,必須要通過partition提定分割槽的值:
hive> load data local inpath '${env:HOME}/stud.txt' into table stud01 partition(grade='2009');
1.3查詢分割槽資料
對於分割槽,可能每一個分割槽中的資料都非常的多:
分割槽查詢限制:預設情況下,在查詢時,可以不用帶分割槽的條件
使用者配置:
在使用者目錄下建立.hiverc值為:
hive.mapred.mode=nonstrict
修改成strict就必須要查詢時有分割槽的條件,修改成nonstrict可以不用寫:
hive>select * from stu01 where grade ="2009"
在 Hive-site.xml配置,可以統一使用。
1.4檢視分割槽
hive>show partitions stu01;
1.5建立多級目錄
hive> create table stud01(
> id string,
> name string,
> age int
> )
> partitioned by (grade string,major string)
> row format delimited
> fields terminated by '\t';
1.6動態分割槽
如果使用load匯入 資料,則分割槽的值,是使用者硬編碼指定,且無法動態。
但是如果從一個表,向另一個表中匯入資料,則可以動態的建立分割槽,但是分割槽的欄位,必須是最後一個欄位。
查詢是否支援動態的分割槽:
指定動態分割槽 mm=name;
hive> insert overwrite table stud03 partition(mm) select id,age,grade,major,name from stud02;
2.排序
3種關鍵字:
Order - 全排,速度比較慢,預設使用一個reducer。
Distribute by (..) 根據指定欄位的hash值%reduce個數 放到不同的檔案中。
Distribute by (..) sort by(...) 排序,-部分排序(每一個reduce內部排序)。
Cluster by = distrubte + sort (部分排序)
2.1.全排序
hive> insert overwrite local directory '${env:HOME}/out001'
>row format delimited
>fields terminated by '\t'
>select name ,id ,age from stu01 order by (name) asc;
可以指定asc(升序)預設,或是desc(降序)
2.2.部分排序
hive> insert overwrite local directory 'home/keys/out002'
> select * from stud01 distribute by(id) sort by (name);
Cluster by (id) = distribute by(id) sort by(id)
3.分桶
關鍵字:distributed
3.1建立表
hive> create table stud02(
> id string,
> name string,
> age int
> )
> clustered by (id) into 3 buckets
> row format delimited
> fields terminated by '\t';
3.2檢視資料
hive> desc formatted stu002;
3.3匯入資料
如果一個表是分桶的,通過load匯入的資料,還是不會分桶的。
向一個分桶的表中的儲存資料,必須要使用 insert select ...從其他的資料表中查詢資料:
hive>insert overweite table stu002 select id,name,age from stu01 cluster by (id);
此時的表既排序又分桶。
4.儲存格式
行儲存和列儲存
資料
行儲存:
適合查詢所有的資料(快)
型別:textfile,squence,avro(json)
使用:mysql oracle
列儲存
適合查詢某一列的資料(快)
使用: orcfile,rcfile,parquet,hbase
4.1sequenceFile
匯入資料用insert不能用load,load是檔案copy不會寫成sequenceFile。
4.2avro
檢視 檔案::$ hdfs dfs -text '目錄'
4.3orcfile/rcfile二進位制檔案
hive> create table stud_orcfile(
> id string,
> name string,
> age int
> )
> stored as orcfile
row format delimited 文字檔案,順序檔案需要指定,二進位制不需要
4.4parquet
hive> create table stud_parquet(
> id string,
> name string,
> age int
> )
> stored as parquet;
5.view
邏輯表,裡面沒有資料。不支援load資料。主要功能簡化查詢,封裝查詢,許可權。
它的資料就來一個查詢
hive> create view v1 as select id,name,age from stu01;
show tables 可以顯示v1;
對於沒有指定別名的列會預設為_c0
hive > create view v2 as select count(1),name from stu01;
查詢
hive> select '_c0',name from v2; //注意要加上單引號。不加不通過
hive > create view v2 as select count(1) as cnt,name from stu01;//指定列名
6.連線查詢
在hive中執行查詢時,有一個建議:
1:越小的表,在前面-進行 快取
2:大的資料表,在後面進行mapreduce。
hive> select s.id as sid,s.name sname,b.id bid,b.name bname from stud_seq s left outer join books b on(s.id=b.sid);
hive> select s.id as sid,s.name sname,b.id bid,b.name bname from stud_seq s right outer join books b on(s.id=b.sid);
hive> select s.id as sid,s.name sname,b.id bid,b.name bname from stud_seq s full join outer books b on(s.id=b.sid);
7.子查詢
只支援非相關子查詢,不支援相關子查詢。
非相關子查詢:子查詢可以獨立執行的。
相關子查詢:子語句不能拿出來被單獨執行,有依賴關係。
SELECT * FROM stud WHERE id IN(SELECT sid FROM books GROUP BY sid HAVING COUNT(sid)=0);
SELECT sid FROM books GROUP BY sid HAVING COUNT(sid)=2;
SELECT * FROM stud WHERE (SELECT COUNT(1) FROM books WHERE books.sid=stud.id)=0;
SELECT COUNT(1) FROM books WHERE books.sid=stud.id
8.檢視執行計劃
通過explain + sql語句檢視sql的執行計劃