HIVE初步(一):基本語法
建立表
首先看一個:chestnut:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] `default`.`video_all`( `cuid` string, `totalpv` int COMMENT '總 pv', `activedays` int COMMENT '活躍天數', `firstday` string, `lastday` string ) PARTITIONED BY ( `day` string COMMENT 'partition_stat_date SAMPLE 20160124' ) CLUSTERED BY (`cuid`) SORTED BY (`cuid` desc) INTO 4 BUCKETS ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LOCATION 'hdfs://yq01-build-hdfs.dmop.baidu.com:54310/user/midway/video_statistics/monthly'
create table語法和sql語句非常類似,特別的是以下幾點
1.external可選:external為外部表,在建表的同時指定一個指向實際資料的路徑(LOCATION),建立外部表僅記錄資料所在的路徑,不對資料的位置做任何改變,刪除外部表時也只刪除元資料,不會刪除表中的資料;不選external時,會將資料移動到資料倉庫指向的路徑,刪除時資料跟著被刪除掉。
2.PARTITIONED BY 分割槽方式
根據某一個key(不在create table裡面)對資料進行分割槽,如本例中,體現在HDFS上就是 table目錄下有多個不同的分割槽資料夾,eg:hdfs://yq01-build-hdfs.dmop.baidu.com:54310/user/midway/video_statistics/monthly/20160124
3.ROW FORMAT DELIMITED FIELDS TERMINATED BY
hive沒有嚴格的格式要求,只需要指定檔案中列分隔和行分隔方式即可
4.CLUSTERED BY
除partition之外,還可以通過cluster進行分桶。Hive採用對列值雜湊,然後除以桶的個數求餘的方式決定該條記錄存放在哪個桶當中。好處有:1.查詢效率更高;2.取樣更方便
修改表
#增加分割槽 ALTER TABLE `default`.`video_all` ADD PARTITION (day='20190401') #表重新命名 ALTER TABLE `default`.`video_all` RENAME TO `video_eg` #增加/更新列 ALTER TABLE `default`.`video_all` ADD COLUMNS (user_type string) #插入(若重複則覆蓋) INSERT OVERWRITE [LOCAL] DIRECTORY directory1 SELECT ... FROM ... #select SELECT [ALL | DISTINCT] select_expr, select_expr, ... FROM table_reference [WHERE where_condition] [GROUP BY col_list [HAVING condition]] [CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list] ] [LIMIT number] #join SELECT a.* FROM a JOIN b ON (a.id = b.id)
語法基本和sql類似,需要注意的是,MapReduce的執行方式:
1.order by:全域性排序,因而只有一個reducer。資料規模大時,時延較久
2.sort by:可以是多個reducer,當reducer設定大於1時,保證每個reducer中的排序
3.distribute by:根據指定的內容將資料分到同一個reducer
4.cluster by = distribute by + sort by
4.join by:
a.如果join中多個表的 join key 是同一個,則 join 會被轉化為單個 map/reduce 任務
b.不同join key,則有幾個join key,則有幾個map/reduce任務
c.reducer 會快取 join 序列中除了最後一個表的所有表的記錄,再通過最後一個表將結果序列化到檔案系統。這一實現有助於在 reduce 端減少記憶體的使用量。實踐中,應該把最大的那個表寫在最後(否則會因為快取浪費大量記憶體) 。
儲存select結果
#新建立表存資料 create table new_table as select * from old_table #插入已存在的表 insert into new_table select col_0, col_1 from old_table #存入特定路徑 insert overwrite [local] directory '/home/hadoop/test' select * from old_table;