內部表&外部表
在Hive創建表的語法中有一個關鍵字是EXTERNAL,該關鍵字表示表的類型,在Hive中一共有兩種類型的表:MANAGED_TABLE(內部表)和EXTERNAL_TABLE(外部表)。如果沒有加EXTERNAL關鍵字,則創建表都是管理表,兩種表有以下的區別:
- 在導入數據到外部表,數據並沒有移動到自己的數據倉庫目錄下(如果指定了location的話),也就是說外部表中的數據並不是由Hive自己來管理的,而內部表則不一樣,是由數據倉庫來管理的;
- 在刪除表的時候,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格式:
- TEXTFILE:默認存儲格式,數據可以使用任意分隔符進行分割,每一行爲一條記錄。默認無壓縮,可以用gzip、snappy等方式對數據壓縮,但是會造成無法對數據切分並行操作。
- SEQUENCEFILE: 對hdfs上的數據進行二進制格式編碼,存儲進行了壓縮,有利於減少IO,也是基於行存儲。
- RCFILE:是基於sequencefile存儲,但是是基於列存儲,列值通常重複值很多,所以更利於壓縮。這種方式壓縮率更高。他先對行進行分組 ,在對列進行合併。比如我們select 表中的一列數據時,只會對該列的數據進行處理,但是其他存儲方式不論select幾列會對所有數據都讀取出來。但是當select 全列時,rcfile反而不如sequencefile的性能高了。
- ORC:(Optimized Record Columnar),ORC在RCFile的基礎上進行了一定的改進,使用ORC文件格式可以提高hive讀、寫和處理數據的能力。
- PARQUET:列式存儲,支持嵌套的數據模型,類似於Protocol Buffers,每一個數據模型的schema包含多個字段,每一個字段又可以包含多個字段,每一個字段有三個屬性:重複數、數據類型和字段名,重複數可以是以下三種:required(出現1次),repeated(出現0次或多次),optional(出現0次或1次)。每一個字段的數據類型可以分成兩種:group(複雜類型)和primitive(基本類型)
- 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')
- LOAD DATA是加載數據到hive表中,源數據可以是本地文件也可以是HDFS文件
- 如果有LOCAL表示從本地文件系統加載,無LOCAL表示從HDFS中加載數據<文件直接被移動,不是拷貝>
- OVERWRITE表示會覆蓋表中數據或者指定分區數據,沒有該字段則是APPEND模式,如果加載了同樣的文件名字,則會被自動重新命名
實戰
-
建表
create table test_user ( user_id int comment 'userID', user_name string comment 'userName' ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
-
準備數據,用戶id和用戶名字,用,分割,存在hive_table_data.txt
2020001,小王 2020002,小李 2020003,小明 2020004,阿狗 2020005,姚明
-
從本地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
-
從本地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
-
刪除表,刪除表後,元數據和數據文件也相應刪除
drop table test_user
查看HDFS路徑,發現數據也刪除了:
hadoop fs -ls /user/hive/warehouse/test_user ls: `/user/hive/warehouse/test_user': No such file or directory
-
外部表創建&刪除,創建外部表指定數據路徑,將剛剛的文件上傳到需要指定的路徑中,可以看到可以查詢到數據
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 姚明
-
刪除外部表
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