資料倉庫和hive語句中的分割槽表和分桶表
資料倉庫中從各資料來源獲取資料以及在資料倉庫內的資料轉換和流動都可以認為是ETL(抽取Extra,轉化Transfer,裝載Load)的過程,ETL是資料倉庫的流水線.
資料倉庫(data warehouse)與資料庫的區別:
- 資料倉庫(data warehouse)-->面向分析, 不生產資料, 不消費資料, 只是資料的搬運工, 為了分析方便
- OLTP-->面向事務, 操作型處理, 就是關係型資料庫(RDBMS),如: MySQL oracle sqlserver db2
- OLAP-->面向分析, 分析型處理, 就是資料倉庫, 面對的是歷史資料(歷史資料中的一部分就是來自資料庫)展開分析.
- 源資料層(ODS): 直接引用外圍的資料, 沒有統一格式的, 不會直接應用使用,不利於分析
- 資料倉庫層(DW): 來自於ODS, 要經過ETL的過程, 格式統一, 資料規整, 乾淨清潔
- 資料應用層(DA): 要去用DW層資料, 真正的資料使用者.
資料倉庫中資料的流轉流程: ODS-->DW-->DA
元資料: 描述資料的資料, 解析資料的資料, 或者說是解析性資料,相當於資料字典
資料倉庫元資料: 記錄資料倉庫維護過程中的點點滴滴.
資料倉庫:
- 提供資料儲存能力
- 能夠進行ETL的能力
Hive:
hive是基於hadoop的一個數據倉庫工具, 將結構化資料對映成一張表, 通過sql查詢, 本質上是把sql轉化成了mr程式執行.
所謂hive的分割槽(partitioned by)表就是以資料夾的形式把檔案管理的更加清晰, 不同的分割槽內容代表著不同的資料夾, 當表是分割槽表的時候, 直接往表的目錄下放資料的方式已經不行了, 德通過分割槽表特有的載入資料方式.
關於分割槽表的總結:
- 分割槽表是為了減少查詢時候的全表掃描而出現.
- 分割槽表的現象就是在表的資料夾下多了一個資料夾, 而資料夾的名字就是分割槽 欄位=分割槽值
- 分割槽欄位的值在查詢的時候會顯示出來, 但是並不代表結構化資料中有這個欄位, 分割槽欄位事一個虛擬欄位, 只是用來標識檔案, 方便使用者查詢的時候根據這個欄位進行過濾, 從而減少全域性掃描.
- 分割槽表的資料通過load data的方式載入(在客戶端執行), 載入的時候要指定分割槽的值(這個值就是這批資料資料夾名字的值).
- 關於分割槽欄位一定不會是表中存在的欄位
分割槽表在實際中的意義: 根據需求把資料管理在不同資料夾下.
分割槽表建表語句:
Create table t_user(id int,name string) partitioned by (country string) row format delimited fields terminated by ',';
Load data local inpath‘/root/hivedata/china.txt’ into table t_user2 partiton(country=’China’);
分桶表(分簇表):
Clustered by (欄位) intonum_buckets buckets
翻譯: 把資料按照指定的欄位分成幾桶(分成幾個部分)
如:按照性別分成2個部分
Clustered by (sex) into 2 buckets
1. 分桶表把資料分開了, 分開幾個部分就是幾桶
2. 分桶表根據欄位分, 這個欄位一定是表中的欄位
3. 在檔案的層面上對資料進行分開
分桶表的操作;
1. 分桶表的功能預設不開啟, 需要自己手動開啟
Set hive.enforce.bucketing=true
2. 分成幾桶也需要自己指定
Set mapreduce.job.reduces=N
總結分桶表:
1. 分桶表在檔案層面, 把資料分開了,分開的語句是
Clustered by (欄位) into num_bucketsbuckets, 其中的欄位必須是表中已經存在的欄位
2. 預設分桶規則: hash_function(欄位)%桶的個數
當欄位是int型別的時候hash_function(欄位)=欄位本身
如果是其他型別, 比較複雜, 欄位值雜湊 % 桶的個數
3. 分桶分成幾個部分, 實際上就是reducetask執行的個數, 個數是幾, 桶就是幾, 最終檔案就是幾個部分,因此分桶的資料要想成功必須執行mr程式.
分桶表的出現, 提高了join查詢時的效率, 減少了笛卡爾積的數量
使用規則: 把左右兩邊按照join欄位分桶即可.
分桶表語法:
1. 指定開啟分桶
Set.hive.enforce.buketing=true;
Set mapreduce.job.reduces=4;(分桶個數)
2. 建立一個用於分桶的表
drop table stu_buck;
create table stu_buck(Sno int,Sname string,Sex string,Sage int,Sdeptstring)
clustered by(Sno) sorted by(Sno DESC) into 4 buckets rowformat delimited fields terminated by ',';
3. 建立student表,並指定分隔符
create table student(Sno int,Sname string,Sex string,Sage int,Sdept string)
row format delimited fields terminated by ',';
4. 把資料對映到student
load data local inpath '/root/hivedata/students.txt' intotable student;
5. 將資料匯入分桶表,方式: insert + select insert資料來自於select查詢結果
insert overwrite table stu_buck select * from student clusterby(Sno);