1. 程式人生 > >hive的內部表與外部表建立

hive的內部表與外部表建立

最近才接觸Hive。學到了一些東西,就先記下來,免得以後忘了。

1.建立表的語句:
Create [EXTERNAL] TABLE [IF NOT EXISTS] table_name 
[(col_name data_type [COMMENT col_comment], ...)] 
[COMMENT table_comment] 
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] 
[CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] 


[ROW FORMAT row_format] 
[STORED AS file_format] 
[LOCATION hdfs_path]

CREATE TABLE 建立一個指定名字的表。如果相同名字的表已經存在,則丟擲異常;使用者可以用 IF NOT EXIST 選項來忽略這個異常。
EXTERNAL 關鍵字可以讓使用者建立一個外部表,在建表的同時指定一個指向實際資料的路徑(LOCATION),Hive 建立內部表時,會將資料移動到資料倉庫指向的路徑;若建立外部表,僅記錄資料所在的路徑,不對資料的位置做任何改變。在刪除表的時候,內部表的元資料和資料會被一起刪除,而外部表只刪除元資料,不刪除資料。
如果檔案資料是純文字,可以使用 STORED AS TEXTFILE。如果資料需要壓縮,使用 STORED AS SEQUENCE 。

有分割槽的表可以在建立的時候使用 PARTITIONED BY 語句。一個表可以擁有一個或者多個分割槽,每一個分割槽單獨存在一個目錄下。而且,表和分割槽都可以對某個列進行 CLUSTERED BY 操作,將若干個列放入一個桶(bucket)中。也可以利用SORT BY 對資料進行排序。這樣可以為特定應用提高效能。
建立普通的表:
create table test_table (id int,name string,no int) row format delimited fields terminated by ',' stored as textfile ;//指定了欄位的分隔符,hive只支援單個字元的分隔符。hive預設的分隔符是\001

建立帶有partition的表:
create table test_partition (id int,name string,no int)partitioned by (dt string)  row format delimited fields terminated by ',' stored as textfile ;
load data local inpath '/home/zhangxin/hive/test_hive.txt' overwrite into table test_partition partition (dt='2012-03-05');
建立帶有Bucket的表:
create table test_bucket (id int,name string,no int)partitioned by (dt string) clustered by (id) into 3 buckets row format delimited fields terminated by ',' stored as textfile ;
建立external表:
create external table test_external (id int,name string,no int)row format delimited fields terminated by ',' location '/home/zhangxin/hive/test_hive.txt';
建立與已知表相同結構的表 Like:只複製表的結構,而不復製表的內容。
create table test_like_table like test_bucket;

2.刪除表:
Drop Table tablename;

刪除一個內部表的同時會同時刪除表的元資料和資料。刪除一個外部表,只刪除元資料而保留資料。

3.修改已經存在的表:
alter table
Alter table 語句允許使用者改變現有表的結構。使用者可以增加列/分割槽,表本身重新命名。

1》增加分割槽 Add Partitions:
ALTER TABLE table_name ADD partition_spec [ LOCATION 'location1' ] partition_spec [ LOCATION 'location2' ]
其中partition_spec 的格式為:PARTITION (partition_col = partition_col_value, partition_col = partiton_col_value, ...)
使用者可以用 ALTER TABLE ADD PARTITION 來向一個表中增加分割槽。當分割槽名是字串時加引號。

alter table test_partition add partition (dt='2012-03-06') location '/home/zhangxin/hive/test_hive.txt';

2》刪除分割槽 drop Partition:
ALTER TABLE table_name DROP partition_spec, partition_spec,...
使用者可以用 ALTER TABLE DROP PARTITION 來刪除分割槽。分割槽的元資料和資料將被一併刪除。

alter table test_partition drop partition (dt='2012-03-06')

3》對錶進行重新命名 rename to:
ALTER TABLE table_name RENAME TO new_table_name
這個命令可以讓使用者為表更名。資料所在的位置和分割槽名並不改變。換而言之,老的表名並未“釋放”,對老表的更改會改變新表的資料。
alter table test_partition rename to new_test_partition;

4》對錶中的某一列進行修改,包括列的名稱/列的資料型別/列的位置/列的註釋
ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
這個命令可以允許使用者修改一個列的名稱、資料型別、註釋或者位置
create table test_col_change (a int,b int, c int);

修改列的名稱,後面一定要加上資料型別:
alter table test_col_change change a a1 int;

alter table test_col_change  change b b1 string;

ALTER TABLE test_col_change CHANGE a a1 INT; 將 a 列的名字改為 a1.

ALTER TABLE test_col_change CHANGE a a1 STRING AFTER b; 將 a 列的名字改為 a1,a 列的資料型別改為 string,並將它放置在列 b 之後。新的表結構為: b int, a1 string, c int.

ALTER TABLE test_col_change CHANGE b b1 INT FIRST; 會將 b 列的名字修改為 b1, 並將它放在第一列。新表的結構為: b1 int, a string, c int.

注意:對列的改變只會修改 Hive 的元資料,而不會改變實際資料。使用者應該確定保證元資料定義和實際資料結構的一致性。

5》新增/替換列Add/Replace Columns
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)
ADD COLUMNS 允許使用者在當前列的末尾增加新的列,但是在分割槽列之前。

alter table test_col_change add columns (d int);
describe test_col_change;
OK
a1    int    
b1    string    
c    int    
d    int    

REPLACE COLUMNS 刪除以後的列,加入新的列。只有在使用 native 的 SerDE(DynamicSerDe or MetadataTypeColumnsetSerDe)的時候才可以這麼做。
alter table test_col_change replace columns (c int);
describe test_col_change;                           
OK
c    int    

6》修改表的屬性Alter Table Properties:

ALTER TABLE table_name SET TBLPROPERTIES table_properties 
table_properties: : (property_name = property_value, property_name = property_value, ... )
使用者可以用這個命令向表中增加 metadata,目前 last_modified_user,last_modified_time 屬性都是由 Hive 自動管理的。使用者可以向列表中增加自己的屬性。可以使用 DESCRIBE EXTENDED TABLE 來獲得這些資訊。
alter table test_col_change set tblproperties ('key1'='value1');
可以通過 describe extended  test_col_change; 查看錶的屬性資訊。

7》修改表的序列化和反序列化屬性:
ALTER TABLE table_name SET SERDE serde_class_name [WITH SERDEPROPERTIES serde_properties]
ALTER TABLE table_name SET SERDEPROPERTIES serde_properties
serde_properties: : (property_name = property_value, property_name = property_value, ... )

這個命令允許使用者向 SerDe 物件增加使用者定義的元資料。Hive 為了序列化和反序列化資料,將會初始化 SerDe 屬性,並將屬性傳給表的 SerDe。如此,使用者可以為自定義的 SerDe 儲存屬性。

8》修改表的檔案儲存格式組織方式:
ALTER TABLE table_name SET FILEFORMAT file_format
ALTER TABLE table_name CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name, ...)] INTO num_buckets BUCKETS
這個命令修改了表的物理儲存屬性。

4.將資料載入到表中:
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
當資料被載入至表中時,不會對資料進行任何轉換。Load 操作只是將資料複製/移動至 Hive 表對應的位置。
filepath 可以是:
相對路徑,例如:project/data1
絕對路徑,例如: /user/hive/project/data1
包含模式的完整 URI,例如:hdfs://namenode:9000/user/hive/project/data1
載入的目標可以是一個表或者分割槽。如果表包含分割槽,必須指定每一個分割槽的分割槽名。
filepath 可以引用一個檔案(這種情況下,Hive 會將檔案移動到表所對應的目錄中)或者是一個目錄(在這種情況下,Hive 會將目錄中的所有檔案移動至表所對應的目錄中)。
如果指定了 LOCAL,那麼:load 命令會去查詢本地檔案系統中的 filepath。如果發現是相對路徑,則路徑會被解釋為相對於當前使用者的當前路徑。使用者也可以為本地檔案指定一個完整的 URI,比如:file:///user/hive/project/data1.load 命令會將 filepath 中的檔案複製到目標檔案系統中。
目標檔案系統由表的位置屬性決定。被複制的資料檔案移動到表的資料對應的位置。如果沒有指定 LOCAL 關鍵字,如果 filepath 指向的是一個完整的 URI,hive 會直接使用這個 URI。 否則:如果沒有指定 schema 或者 authority,Hive 會使用在 hadoop 配置檔案中定義的 schema 和 authority,fs.default.name 指定了 Namenode 的 URI。如果路徑不是絕對的,Hive 相對於 /user/ 進行解釋。Hive 會將 filepath 中指定的檔案內容移動到 table (或者 partition)所指定的路徑中。如果使用了 OVERWRITE 關鍵字,則目標表(或者分割槽)中的內容(如果有)會被刪除,然後再將 filepath 指向的檔案/目錄中的內容新增到表/分割槽中。如果目標表(分割槽)已經有一個檔案,並且檔名和 filepath 中的檔名衝突,那麼現有的檔案會被新檔案所替代。