(轉)hive sql 學習筆記

一、 創建表
    在官方的wiki裏,example是這樣的:

  1. CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name   
  2.   [(col_name data_type [COMMENT col_comment], ...)]   
  3.   [COMMENT table_comment]   
  4.   [PARTITIONED BY (col_name data_type   
  5.     [COMMENT col_comment], ...)]   
  6.   [CLUSTERED BY (col_name, col_name, ...)   
  7.   [SORTED BY (col_name [ASC|DESC], ...)]   
  8.   INTO num_buckets BUCKETS]   
  9.   [ROW FORMAT row_format]   
  10.   [STORED AS file_format]   
  11.   [LOCATION hdfs_path]  
View Code

 

 [ROW FORMAT DELIMITED]關鍵字,是用來設置創建的表在加載數據的時候,支持的列分隔符;
[STORED AS file_format]關鍵字是用來設置加載數據的數據類型。Hive本身支持的文件格式只有:Text File,Sequence File。如果文件數據是純文本,可以使用 [STORED AS TEXTFILE]。如果數據需要壓縮,使用 [STORED AS SEQUENCE] 。通常情況,只要不需要保存序列化的對象,我們默認採用[STORED AS TEXTFILE]。

 

    那麼我們創建一張普通的hive表,hive sql就如下:

  1. CREATE TABLE test_1(id INTname STRING, city STRING) SORTED BY TEXTFILE ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’  ;

    其中,hive支持的字段類型,並不多,可以簡單的理解爲數字類型和字符串類型,詳細列表如下:

  1. TINYINT   
  2. SMALLINT  
  3. INT  
  4. BIGINT  
  5. BOOLEAN   
  6. FLOAT  
  7. DOUBLE  
  8. STRING  

 

注意partitioned by 的位置:

create table webdata2(vstart string,vend string,hdid int,userid  int,sid int,refsid  int,active  int,duration int,mdomain string,sdomain string,refsdomain string,ieid    int,refieid string,url     string,totaltime int,param2 int,param4 string,param4code string) partitioned by(pid int,daytime string) row format delimited fields terminated by '\t' stored as SEQUENCEFILE;

    Hive的表,與普通關係型數據庫,如mysql在表上有很大的區別,所有hive的表都是一個文件,它是基於Hadoop的文件系統來做的。

   hive總體來說可以總結爲三種不同類型的表。


1. 普通表 
    普通表的創建,如上所說,不講了。其中,一個表,就對應一個表名對應的文件。

2. 外部表


    EXTERNAL 關鍵字可以讓用戶創建一個外部表,在建表的同時指定一個指向實際數據的路徑(LOCATION),Hive 創建內部表時,會將數據移動到數據倉庫指向的路徑;若創建外部表,僅記錄數據所在的路徑,不對數據的位置做任何改變。在刪除表的時候,內部表的元數據和數據會被一起刪除,而外部表只刪除元數據,不刪除數據。具體sql如下:

  1. CREATE EXTERNAL TABLE test_1(id INTname STRING, city STRING) SORTED BY TEXTFILE ROW FORMAT DELIMITED FIELDS TERMINATED BY'\t’ LOCATION ‘hdfs://http://www.cnblogs.com/..’  

3. 分區表


    有分區的表可以在創建的時候使用 PARTITIONED BY 語句。一個表可以擁有一個或者多個分區,每一個分區單獨存在一個目錄下。而且,表和分區都可以對某個列進行 CLUSTERED BY 操作,將若干個列放入一個桶(bucket)中。也可以利用SORT BY 對數據進行排序。這樣可以爲特定應用提高性能。具體SQL如下:

  1. CREATE TABLE test_1(id INTname STRING, city STRING) PARTITIONED BY (pt STRING) SORTED BY TEXTFILE ROW FORMAT DELIMITED FIELDS TERMINATED BY‘\t’   

    Hive的排序,因爲底層實現的關係,比較不同於普通排序,這裏先不講。

 

     桶的概念,主要是爲性能考慮,可以理解爲對分區內列,進行再次劃分,提高性能。在底層,一個桶其實是一個文件。如果桶劃分過多,會導致文件數量暴增,一旦達到系統文件數量的上限,就杯具了。哪種是最優數量,這個哥也不知道。

 

    分區表實際是一個文件夾,表名即文件夾名。每個分區,實際是表名這個文件夾下面的不同文件。分區可以根據時間、地點等等進行劃分。比如,每天一個分區,等於每天存每天的數據;或者每個城市,存放每個城市的數據。每次查詢數據的時候,只要寫下類似 where pt=2010_08_23這樣的條件即可查詢指定時間得數據。

 

    總體而言,普通表,類似mysql的表結構,外部表的意義更多是指數據的路徑映射。分區表,是最難以理解,也是最hive最大的優勢。之後會專門針對分區表進行講解。

 

二、 加載數據


    Hive不支持一條一條的用insert語句進行插入操作,也不支持update的操作。數據是以load的方式,加載到建立好的表中。數據一旦導入,則不可修改。要麼drop掉整個表,要麼建立新的表,導入新的數據。

官方指導爲:

  1. LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]  

    Hive在數據load這塊,大方向分爲兩種方式,load文件或者查詢一張表,或者將某張表裏的額查詢結果插入指定表。
如果劃分更細一點個人歸納總結爲4種不同的方式的load:

 

1. Load data到指定的表 
    直接將file,加載到指定的表,其中,表可以是普通表或者分區表。具體sql如下:

  1. LOAD DATA LOCAL INPATH '/home/admin/test/test.txt' OVERWRITE INTO TABLE test_1  
    關鍵字[OVERWRITE]意思是是覆蓋原表裏的數據,不寫則不會覆蓋。
    關鍵字[LOCAL]是指你加載文件的來源爲本地文件,不寫則爲hdfs的文件。
    其中

     ‘/home/admin/test/test.txt’爲絕對路徑
 

2. load到指定表的分區 
    直接將file,加載到指定表的指定分區。表本身必須是分區表,如果是普通表,導入會成功,但是數據實際不會被導入。具體sql如下:

  1. LOAD DATA LOCAL INPATH '/home/admin/test/test.txt' OVERWRITE INTO TABLE test_1 PARTITION(pt=’xxxx)  
    load數據,hive支持文件夾的方式,將文件夾內的所有文件,都load到指定表中。Hdfs會將文件系統內的某文件夾路徑內的文件,分散到不同的實際物理地址中。這樣,在數據量很大的時候,hive支持讀取多個文件載入,而不需要限定在唯一的文件中。
    
<span style="font-size:12px;"><strong>3. insert+select</strong> </span>


    這個是完全不同於文件操作的數據導入方式。官方指導爲:

  1. Standard syntax:   
  2. INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement    
  3.   
  4. Hive extension (multiple inserts):   
  5. FROM from_statement   
  6. INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1   
  7. [INSERT OVERWRITE TABLE tablename2 [PARTITION ...] select_statement2] ...   
  8.   
  9. Hive extension (dynamic partition inserts):   
  10. INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement  
    這個的用法,和上面兩種直接操作file的方式,截然不同。從sql語句本身理解,就是把查詢到的數據,直接導入另外一張表。這個暫時不仔細分析,之後查詢章節,再細講。


4. alter 表,對分區操作


    在對錶結構進行修改的時候,我們可以增加一個新的分區,在增加新分區的同時,將數據直接load到新的分區當中。

  1. ALTER TABLE table_name ADD  
  2.   partition_spec [ LOCATION 'location1' ]   
  3.   partition_spec [ LOCATION 'location2' ] ... 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章