Hive筆記三之內部表,外部表,分割槽表,桶表
內部表
也稱為受控表,表中的資料受表定義影響,表刪除後表中資料隨之刪除。在COLUMNS_V2表中TBL_TYPE顯示為MANAGED_TABLE
表刪除後實際上是從hdfs上將t1目錄移到回收站中,另外刪除TBLS表中的表定義資訊
hive> drop table t1;
Moved:'hdfs://shb01:9000/user/hive/warehouse/t1' to trash at:hdfs://shb01:9000/user/root/.Trash/Current
OK
Time taken: 1.789 seconds
外部表
資料不受表定義影響,表刪除後資料仍在。
create external table t4_exter1(
id string,name string)
row format delimited
fields terminated by '\t' location'hdfs://shb01:9000/data/';
hive> source /usr/local/data/t4_hql.hql;
在TBLS表中可以看到外部表資訊
也可以在建立表時不指定資料,之後通過alter指定資料
alter table t4_exter1 set location'hdfs://shb01:9000/data/t4';
hive> drop table t4_exter1;
OK
Time taken: 0.274 seconds
外部表只是對資料的引用,如果刪除外部表data/t4的資料不會被刪除,hdfs中/user/hive/warehouse目錄下的資訊不會被刪除,而刪除的只是TBLS表中的表定義資訊。
實際中當系統只有一份公共資料但是多個數據組都需要使用時為避免誤刪除就需要使用外部表。
內部表和外部表之間還可以互相轉換,但是這是個非常危險的操作應儘量避免。
alter table t2 set tblproperties('EXTERNAL'='TRUE');
alter table t2 settblproperties('EXTERNAL'='FALSE');
分割槽表
分割槽表也是內部表,建立表時可以同時為表建立一個或多個分割槽,這樣我們在載入資料時為其指定具體的分割槽,查詢資料時可以指定具體的分割槽從而提高效率,分割槽可以理解為表的一個特殊的列。關鍵字是partitioned。
分割槽表實際上是將表文件分成多個有標記的小檔案方便查詢。
建立分割槽表
hive> create table t5_part(id int,namestring)
> partitioned by (year int,city string)
> row format delimited fields terminated by '\t';
OK
Time taken: 0.349 seconds
檢視分割槽表,其中# Partition Information為分割槽資訊,有兩個分割槽year和city
hive> desc extended t5_part;
OK
id int
name string
year int
city string
# Partition Information
# col_name data_type comment
year int
city string
載入資料
第一次分割槽資訊為year=2010, city=BeiJing
hive> load data local inpath'/usr/local/data/t4' into table t5_partpartition(year=2010,city='BeiJing');
Loading data to table default.t5_partpartition (year=2010, city=BeiJing)
Partition default.t5_part{year=2010,city=BeiJing} stats: [numFiles=1, numRows=0, totalSize=13, rawDataSize=0]
OK
Time taken: 3.317 seconds
第二次分割槽為year=2013, city=ShangHai
hive> load data local inpath'/usr/local/data/t4' into table t5_part partition(year=2013,city='ShangHai');
Loading data to table default.t5_partpartition (year=2013, city=ShangHai)
Partition default.t5_part{year=2013,city=ShangHai} stats: [numFiles=1, numRows=0, totalSize=13, rawDataSize=0]
OK
Time taken: 0.801 seconds
查詢全部資訊
hive> select * from t5_part;
OK
1 jack 2010 BeiJing
2 tom 2010 BeiJing
1 jack 2013 ShangHai
2 tom 2013 ShangHai
Time taken: 0.165 seconds, Fetched: 4row(s)
根據分割槽查詢,分割槽很像是一個特殊的列
hive> select * from t5_part whereyear=2010 and city='BeiJing';
OK
1 jack 2010 BeiJing
2 tom 2010 BeiJing
Time taken: 0.112 seconds, Fetched: 2row(s)
分割槽表載入資料必須指定分割槽否則會報錯
hive> load data local inpath'/usr/local/data/t4' into table t5_part;
FAILED: SemanticException [Error 10062]:Need to specify partition columns because the destination table is partitioned
檢視分割槽表的分割槽資訊
hive> show partitions t5_part;
OK
year=2010/city=BeiJing
year=2013/city=ShangHai
year=2016/city=nanjing
Time taken: 1.685 seconds, Fetched: 3row(s)
hive>
在hadoop下分割槽表是把分割槽當成目錄的
其實我覺得分割槽表在載入資料時就是讓資料帶著標籤入庫方便後續大資料量條件下的查詢操作。
桶表
之前介紹分割槽表是將大的表文件劃分成多個小檔案以利於查詢,但是如果資料分佈不均衡也會影響查詢效率。桶表可以對資料進行雜湊取模目的是讓資料能夠均勻的分佈在表的各個資料檔案中,它其實是對分割槽表的補充。以往查詢時需要將資料全部載入到記憶體中再過濾而分桶後則可以只將表的部分檔案載入到記憶體中提高查詢效率。
分桶表屬於內部表,關鍵字clustered。
hive> sethive.exec.mode.local.auto=true;
hive> set hive.enforce.bucketing=true;
修改引數允許強制分桶,也可以修改hive_site.xml檔案中的引數改為true
<property>
<name>hive.enforce.bucketing</name>
<value>false</value>
<description>Whether bucketing is enforced. If true, whileinserting into the table, bucketing is enforced.</description>
</property>
建立分桶表
下面的例子是根據id取模(id%3),into 3 buckets中的3就是取模的值。
hive> create table t6_bucket (id string)clustered by (id) into 3 buckets;
OK
Time taken: 2.773 seconds
載入資料
桶表資料必須從其他錶轉換
hive> insert into table t6_bucket selectid from t5_part;
不知道怎麼的我的機器反應很慢
可以看到產生3個數據檔案,這個過程有一次說明hive是sql解析引擎最終又轉化為MapReduce任務。
分別產生了3個檔案
下面是hdfs上顯示的其中一個檔案的內容
[[email protected] data]# hadoop fs -text/user/hive/warehouse/t6_bucket/000001_0
16/12/26 06:50:18 WARNutil.NativeCodeLoader: Unable to load native-hadoop library for yourplatform... using builtin-java classes where applicable
1
1
1