Hive實戰-建表相關操作

內部表&外部表

在Hive創建表的語法中有一個關鍵字是EXTERNAL,該關鍵字表示表的類型,在Hive中一共有兩種類型的表:MANAGED_TABLE(內部表)和EXTERNAL_TABLE(外部表)。如果沒有加EXTERNAL關鍵字,則創建表都是管理表,兩種表有以下的區別:

  1. 在導入數據到外部表,數據並沒有移動到自己的數據倉庫目錄下(如果指定了location的話),也就是說外部表中的數據並不是由Hive自己來管理的,而內部表則不一樣,是由數據倉庫來管理的;
  2. 在刪除表的時候,Hive將會把屬於表的元數據和數據全部刪掉;而刪除外部表的時候,Hive僅僅刪除外部表的元數據,數據是不會刪除的。

建表

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
  [(col_name data_type [column_constraint_specification] [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]
  [SKEWED BY (col_name, col_name, ...) 
     ON ((col_value, col_value, ...), (col_value, col_value, ...), ...)
     [STORED AS DIRECTORIES]
  [
   [ROW FORMAT row_format] 
   [STORED AS file_format] 
  ]
  [LOCATION hdfs_path]
  [TBLPROPERTIES (property_name=property_value, ...)]
  [AS select_statement];

CREATE TABLE根據給定名稱創建表。如果已經存在一個具有相同名稱的表或視圖,則會引發錯誤,可以使用IF NOT EXISTS跳過錯誤。表名和列名不區分大小寫,但是SERDE和屬性名稱都是區分大小寫的

ROW FORMAT SERDE

ROW FORMAT DELIMITED是用來設置Hive表在加載數據的時候的列分隔符。默認情況下不同列之間用一個’\001’分割,集合(例如array,map)的元素之間以’\002’隔開,map中key和value用’\003’分割,默認的序列化方式是LazySimpleSerDe

ROW FORMAT SERDE
  'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'field.delim'=',',
  'serialization.format'=',')

ROW FORMAT SERDE用來指定行數據的序列化方式:

ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'

STORED AS

用來設置加載數據的數據類型,目前有以下內置的Hive格式:

  1. TEXTFILE:默認存儲格式,數據可以使用任意分隔符進行分割,每一行爲一條記錄。默認無壓縮,可以用gzip、snappy等方式對數據壓縮,但是會造成無法對數據切分並行操作。
  2. SEQUENCEFILE: 對hdfs上的數據進行二進制格式編碼,存儲進行了壓縮,有利於減少IO,也是基於行存儲。
  3. RCFILE:是基於sequencefile存儲,但是是基於列存儲,列值通常重複值很多,所以更利於壓縮。這種方式壓縮率更高。他先對行進行分組 ,在對列進行合併。比如我們select 表中的一列數據時,只會對該列的數據進行處理,但是其他存儲方式不論select幾列會對所有數據都讀取出來。但是當select 全列時,rcfile反而不如sequencefile的性能高了。
  4. ORC:(Optimized Record Columnar),ORC在RCFile的基礎上進行了一定的改進,使用ORC文件格式可以提高hive讀、寫和處理數據的能力。
  5. PARQUET:列式存儲,支持嵌套的數據模型,類似於Protocol Buffers,每一個數據模型的schema包含多個字段,每一個字段又可以包含多個字段,每一個字段有三個屬性:重複數、數據類型和字段名,重複數可以是以下三種:required(出現1次),repeated(出現0次或多次),optional(出現0次或1次)。每一個字段的數據類型可以分成兩種:group(複雜類型)和primitive(基本類型)
  6. AVRO:Avro是一個數據序列化系統,設計用於支持大批量數據交換的應用。它的主要特點有:支持二進制序列化方式,可以便捷,快速地處理大量數據;動態語言友好,Avro提供的機制使動態語言可以方便地處理Avro數據

另外可以分別指定輸入輸出的格式,但是要相互對應,例如STORED AS TEXTFILE等價於:

STORED AS INPUTFORMAT
  'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'

另外該項設置需要跟ROW FORMAT對照,比方設置了AVRO,那麼ROW FORMAT就要設置序列化方式爲AVRO.

LOCATION

LOCATION指定數據存儲位置,默認會根據Hive默認設置位置

TBLPROPERTIES

TBLPROPERTIES允許使用鍵值對定義自己的元數據。

加載數據

LOAD DATA LOCAL INPATH '/path/to/local/xxx'
OVERWRITE  INTO TABLE table_name
PARTITION (date = '20200101')
  1. LOAD DATA是加載數據到hive表中,源數據可以是本地文件也可以是HDFS文件
  2. 如果有LOCAL表示從本地文件系統加載,無LOCAL表示從HDFS中加載數據<文件直接被移動,不是拷貝>
  3. OVERWRITE表示會覆蓋表中數據或者指定分區數據,沒有該字段則是APPEND模式,如果加載了同樣的文件名字,則會被自動重新命名

實戰

  1. 建表

    create table test_user (
    user_id     int     comment 'userID',
    user_name     string     comment 'userName' 
    )
    ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
    
  2. 準備數據,用戶id和用戶名字,用,分割,存在hive_table_data.txt

    2020001,小王
    2020002,小李
    2020003,小明
    2020004,阿狗
    2020005,姚明
    
  3. 從本地LOAD DATA overwrite方式,覆蓋方式寫入表中

    hive> LOAD DATA LOCAL INPATH '/xx/hive_table_data.txt' OVERWRITE  INTO TABLE test_user;
    Loading data to table default.test_user
    Table default.test_user stats: [numFiles=1, totalSize=75]
    OK
    

    查看hive表中數據:

    hive> select * from test_user;
    OK
    2020001	小王
    2020002	小李
    2020003	小明
    2020004	阿狗
    2020005	姚明
    

    查看HDFS路徑上數據:

    hadoop fs -ls /user/hive/warehouse/test_user
    Found 1 items
    -rwxrwxrwx   3 deploy hive         75 2020-05-08 18:20 /user/hive/warehouse/test_user/hive_table_data.txt
    
  4. 從本地LOAD DATA append方式,append方式同樣名字的文件,會自動進行重命名

    hive> LOAD DATA LOCAL INPATH '/xxx/hive_table_data.txt' INTO TABLE test_user;
    Loading data to table default.test_user
    Table default.test_user stats: [numFiles=2, totalSize=150]
    

    查看HDFS路徑上的數據,可以看到同樣的文件被重命名了:

    hadoop fs -ls /user/hive/warehouse/test_user
    Found 2 items
    -rwxrwxrwx   3 deploy hive         75 2020-05-08 18:20 /user/hive/warehouse/test_user/hive_table_data.txt
    -rwxrwxrwx   3 deploy hive         75 2020-05-08 18:24 /user/hive/warehouse/test_user/hive_table_data_copy_1.txt
    
  5. 刪除表,刪除表後,元數據和數據文件也相應刪除

    drop table test_user
    

    查看HDFS路徑,發現數據也刪除了:

    hadoop fs -ls /user/hive/warehouse/test_user
    ls: `/user/hive/warehouse/test_user': No such file or directory
    
  6. 外部表創建&刪除,創建外部表指定數據路徑,將剛剛的文件上傳到需要指定的路徑中,可以看到可以查詢到數據

    hive> create external table test_user (
        > user_id     int     comment 'userID',
        > user_name     string     comment 'userName'
        > )
        > ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
        > LOCATION '/user/xx/tmp/test_hive/';
    OK
    Time taken: 0.09 seconds
    
    hive> select * from test_user;
    OK
    2020001	小王
    2020002	小李
    2020003	小明
    2020004	阿狗
    2020005	姚明
    2020001	小王
    2020002	小李
    2020003	小明
    2020004	阿狗
    2020005	姚明
    
  7. 刪除外部表

    hive> drop table test_user;
    OK
    
    hadoop fs -ls /user/xx/tmp/test_hive/
    Found 2 items
    -rw-r--r--   3 data_udd bigdata         75 2020-05-08 18:38 /user/xx/tmp/test_hive/hive_table_data.txt
    -rw-r--r--   3 data_udd bigdata         75 2020-05-08 18:38 /user/xx/tmp/test_hive/hive_table_data_copy_1.txt
    

參考

  1. https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL
  2. https://www.cnblogs.com/fanzhenyong/p/9746796.html#_label3
  3. https://www.aboutyun.com//forum.php/?mod=viewthread&tid=7458&extra=page%3D1&page=1&
  4. https://blog.csdn.net/helloxiaozhe/article/details/78442570
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章