hive經常使用命令

Hive基本操做

這是apach的一個子項目。依賴於hadoop 必須有器服務才成。還必需要有一個數據庫。最好使用linux 進行玩耍,若是使用win 會有意想不到的異常。node

 

1. DDL操做
1.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 EXISTS 選項來忽略這個異常。
二、 EXTERNAL關鍵字可讓用戶建立一個外部表,在建表的同時指定一個指向實際數據的路徑(LOCATION)。
Hive 建立內部表時,會將數據移動到數據倉庫指向的路徑;若建立外部表,僅記錄數據所在的路徑,不對數據的位置作任何改變。在刪除表的時候,內部表的元數據和數據會被一塊兒刪除,而外部表只刪除元數據,不刪除數據。
三、 LIKE 容許用戶複製現有的表結構,可是不復制數據。
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name LIKE existing_table;linux

四、 ROW FORMAT DELIMITED
[FIELDS TERMINATED BY char]
[COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char]
[LINES TERMINATED BY char] | SERDE serde_name
[WITH SERDEPROPERTIES
(property_name=property_value, property_name=property_value,...)]
hive建表的時候默認的分割符是'\001',若在建表的時候沒有指明分隔符,load文件的時候文件的分隔符須要是'\001';若文件分隔符不是'001',程序不會報錯,但表查詢的結果會所有爲'null';
用vi編輯器Ctrl+v而後Ctrl+a便可輸入'\001' -----------> ^A
SerDe是Serialize/Deserilize的簡稱,目的是用於序列化和反序列化。
Hive讀取文件機制:首先調用InputFormat(默認TextInputFormat),返回一條一條記錄(默認是一行對應一條記錄)。而後調用SerDe(默認LazySimpleSerDe)的Deserializer,將一條記錄切分爲各個字段(默認'\001')。
Hive寫文件機制:將Row寫入文件時,主要調用OutputFormat、SerDe的Seriliazer,順序與讀取相反。
可經過desc formatted 表名;進行相關信息查看。
當咱們的數據格式比較特殊的時候,能夠自定義SerDe。
五、 PARTITIONED BY
在hive Select查詢中通常會掃描整個表內容,會消耗不少時間作不必的工做。有時候只須要掃描表中關心的一部分數據,所以建表時引入了partition分區概念。
分區表指的是在建立表時指定的partition的分區空間。一個表能夠擁有一個或者多個分區,每一個分區以文件夾的形式單獨存在表文件夾的目錄下。表和列名不區分大小寫。分區是以字段的形式在表結構中存在,經過describe table命令能夠查看到字段存在,可是該字段不存放實際的數據內容,僅僅是分區的表示。算法

六、 STORED AS SEQUENCEFILE|TEXTFILE|RCFILE
若是文件數據是純文本,可使用 STORED AS TEXTFILE。若是數據須要壓縮,使用 STORED AS SEQUENCEFILE。
TEXTFILE是默認的文件格式,使用DELIMITED子句來讀取分隔的文件。
六、CLUSTERED BY INTO num_buckets BUCKETS
對於每個表(table)或者分,Hive能夠進一步組織成桶,也就是說桶是更爲細粒度的數據範圍劃分。Hive也是針對某一列進行桶的組織。Hive採用對列值哈希,而後除以桶的個數求餘的方式決定該條記錄存放在哪一個桶當中。
把表(或者分區)組織成桶(Bucket)有兩個理由:
(1)得到更高的查詢處理效率。桶爲表加上了額外的結構,Hive 在處理有些查詢時能利用這個結構。具體而言,鏈接兩個在(包含鏈接列的)相同列上劃分了桶的表,可使用 Map 端鏈接 (Map-side join)高效的實現。好比JOIN操做。對於JOIN操做兩個表有一個相同的列,若是對這兩個表都進行了桶操做。那麼將保存相同列值的桶進行JOIN操做就能夠,能夠大大較少JOIN的數據量。
(2)使取樣(sampling)更高效。在處理大規模數據集時,在開發和修改查詢的階段,若是能在數據集的一小部分數據上試運行查詢,會帶來不少方便。數據庫

1.2. 修改表
增長分區:
ALTER TABLE table_name ADD PARTITION (dt='20170101') location
'/user/hadoop/warehouse/table_name/dt=20170101'; //一次添加一個分區
ALTER TABLE table_name ADD PARTITION (dt='2008-08-08', country='us') location
'/path/to/us/part080808' PARTITION (dt='2008-08-09', country='us') location
'/path/to/us/part080809'; //一次添加多個分區
刪除分區
ALTER TABLE table_name DROP IF EXISTS PARTITION (dt='2008-08-08');
ALTER TABLE table_name DROP IF EXISTS PARTITION (dt='2008-08-08', country='us');緩存

修改分區
ALTER TABLE table_name PARTITION (dt='2008-08-08') RENAME TO PARTITION (dt='20080808');
添加列
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name STRING);
注:ADD是表明新增一個字段,新增字段位置在全部列後面(partition列前)
REPLACE則是表示替換表中全部字段。
修改列
test_change (a int, b int, c int);
ALTER TABLE test_change CHANGE a a1 INT; //修改a字段名
// will change column a's name to a1, a's data type to string, and put it after column b. The new table's structure is: b int, a1 string, c int
ALTER TABLE test_change CHANGE a a1 STRING AFTER b;
// will change column b's name to b1, and put it as the first column. The new table's structure is: b1 int, a ints, c int
ALTER TABLE test_change CHANGE b b1 INT FIRST;
表重命名
ALTER TABLE table_name RENAME TO new_table_name
1.3. 顯示命令
show tables;
顯示當前數據庫全部表
show databases |schemas;
顯示全部數據庫
show partitions table_name;
顯示錶分區信息,不是分區表執行報錯
show functions;
顯示當前版本hive支持的全部方法
desc extended table_name;
查看錶信息
desc formatted table_name;
查看錶信息(格式化美觀)
describe database database_name;
查看數據庫相關信息編輯器

2. DML操做2.1. Load
在將數據加載到表中時,Hive不會進行任何轉換。加載操做是將數據文件移動到與Hive表對應的位置的純複製/移動操做。
語法結構
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO
TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
說明:
一、 filepath
相對路徑,例如:project/data1
絕對路徑,例如:/user/hive/project/data1
完整 URI,例如:hdfs://namenode:9000/user/hive/project/data1
filepath能夠引用一個文件(在這種狀況下,Hive將文件移動到表中),或者它能夠是一個目錄(在這種狀況下,Hive將把該目錄中的全部文件移動到表中)。
二、 LOCAL
若是指定了 LOCAL, load命令將在本地文件系統中查找文件路徑。
load 命令會將 filepath中的文件複製到目標文件系統中。目標文件系統由表的位置屬性決定。被複制的數據文件移動到表的數據對應的位置。
若是沒有指定 LOCAL 關鍵字,若是 filepath 指向的是一個完整的 URI,hive 會直接使用這個 URI。 不然:若是沒有指定 schema 或者 authority,Hive 會使用在 hadoop 配置文件中定義的 schema 和 authority,fs.default.name 指定了 Namenode 的 URI。
三、 OVERWRITE
若是使用了 OVERWRITE 關鍵字,則目標表(或者分區)中的內容會被刪除,而後再將 filepath 指向的文件/目錄中的內容添加到表/分區中。
若是目標表(分區)已經有一個文件,而且文件名和 filepath 中的文件名衝突,那麼現有的文件會被新文件所替代。
2.2. Insert
Hive中insert主要是結合select查詢語句使用,將查詢結果插入到表中,例如:
insert overwrite table stu_buck
select * from student cluster by(Sno);
須要保證查詢結果列的數目和須要插入數據表格的列數目一致.
若是查詢出來的數據類型和插入表格對應的列數據類型不一致,將會進行轉換,可是不能保證轉換必定成功,轉換失敗的數據將會爲NULL。
能夠將一個表查詢出來的數據插入到原表中, 結果至關於自我複製了一份數據。
Multi Inserts多重插入:
from source_table
insert overwrite table tablename1 [partition (partcol1=val1,partclo2=val2)] select_statement1
insert overwrite table tablename2 [partition (partcol1=val1,partclo2=val2)] select_statement2..
Dynamic partition inserts動態分區插入:
INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement
動態分區是經過位置來對應分區值的。原始表select出來的值和輸出partition的值的關係僅僅是經過位置來肯定的,和名字並無關係。
導出表數據
語法結構
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 SELECT ... FROM ...
multiple inserts:
FROM from_statement
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1
[INSERT OVERWRITE [LOCAL] DIRECTORY directory2 select_statement2] ...
數據寫入到文件系統時進行文本序列化,且每列用^A來區分,\n爲換行符。ide

2.3. Select
基本的Select操做
語法結構
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table_reference
JOIN table_other ON expr
[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]
說明:
一、order by 會對輸入作全局排序,所以只有一個reducer,會致使當輸入規模較大時,須要較長的計算時間。
二、sort by不是全局排序,其在數據進入reducer前完成排序。所以,若是用sort by進行排序,而且設置mapred.reduce.tasks>1,則sort by只保證每一個reducer的輸出有序,不保證全局有序。
三、distribute by(字段)根據指定字段將數據分到不一樣的reducer,分發算法是hash散列。
四、Cluster by(字段) 除了具備Distribute by的功能外,還會對該字段進行排序。
若是distribute和sort的字段是同一個時,此時,cluster by = distribute by + sort byoop

3. Hive join
Hive中除了支持和傳統數據庫中同樣的內關聯、左關聯、右關聯、全關聯,還支持LEFT SEMI JOIN和CROSS JOIN,但這兩種JOIN類型也能夠用前面的代替。
Hive 支持等值鏈接(a.id = b.id),不支持非等值(a.id>b.id)的鏈接,由於非等值鏈接很是難轉化到 map/reduce 任務。另外,Hive 支持多 2 個以上表之間的join。
寫 join 查詢時,須要注意幾個關鍵點: 
l join 時,每次 map/reduce 任務的邏輯:
reducer 會緩存 join 序列中除了最後一個表的全部表的記錄,再經過最後一個表將結果序列化到文件系統。這一實現有助於在 reduce 端減小內存的使用量。實踐中,應該把最大的那個表寫在最後(不然會由於緩存浪費大量內存)。
l LEFT,RIGHT 和 FULL OUTER 關鍵字用於處理 join 中空記錄的狀況
SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key)
對應全部 a 表中的記錄都有一條記錄輸出。輸出的結果應該是 a.val, b.val,當 a.key=b.key 時,而當 b.key 中找不到等值的 a.key 記錄時也會輸出:
a.val, NULL
因此 a 表中的全部記錄都被保留了;
「a RIGHT OUTER JOIN b」會保留全部 b 表的記錄。
l Join 發生在 WHERE 子句以前。
若是你想限制 join 的輸出,應該在 WHERE 子句中寫過濾條件——或是在 join 子句中寫。這裏面一個容易混淆的問題是表分區的狀況:
SELECT a.val, b.val FROM a
LEFT OUTER JOIN b ON (a.key=b.key)
WHERE a.ds='2009-07-07' AND b.ds='2009-07-07'
這會 join a 表到 b 表(OUTER JOIN),列出 a.val 和 b.val 的記錄。WHERE 從句中可使用其餘列做爲過濾條件。可是,如前所述,若是 b 表中找不到對應 a 表的記錄,b 表的全部列都會列出 NULL,包括 ds 列。也就是說,join 會過濾 b 表中不能找到匹配 a 表 join key 的全部記錄。這樣的話,LEFT OUTER 就使得查詢結果與 WHERE 子句無關了。解決的辦法是在 OUTER JOIN 時使用如下語法:
SELECT a.val, b.val FROM a LEFT OUTER JOIN b
ON (a.key=b.key AND
b.ds='2009-07-07' AND
a.ds='2009-07-07')
這一查詢的結果是預先在 join 階段過濾過的,因此不會存在上述問題。這一邏輯也能夠應用於 RIGHT 和 FULL 類型的 join 中。
l Join 是不能交換位置的。
不管是 LEFT 仍是 RIGHT join,都是左鏈接的。
SELECT a.val1, a.val2, b.val, c.val
FROM a
JOIN b ON (a.key = b.key)
LEFT OUTER JOIN c ON (a.key = c.key)
先 join a 表到 b 表,丟棄掉全部 join key 中不匹配的記錄,而後用這一中間結果和 c 表作 join。spa

相關文章
相關標籤/搜索