Hive中建立表的完整語法以下:node
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name正則表達式
[ (col_name data_type [COMMET col_comment], . . .)]express
[COMMENT table_comment]apache
[PARTITIONED BY (col_name data_type [COMMENT col_comment], . . . )]緩存
[CLUSTERED BY (col_name, col_name, . . . )]oop
[SORTED BY (col_name [ASC|DESC], . . . ) INFO num_buckets BUCKETS]大數據
[ROW FORMAT row_format]spa
[STORED AS file_format]orm
[LOCATION hdfs_path]對象
CREATE TABLE:用於建立一個指定名稱的表,若是相同名字的表已經存在,則拋出異常,能夠用 IF NOT EXISTS選項來忽略這個異常。
EXTERNAL:該關鍵字可讓用戶建立一個外部表,在建立表的同時指定一個指向實際數據的的路徑(LOCATION).
COMMENT:能夠爲表和字段增長註釋
ROW FORMAT:用戶在建表的時候能夠自定義SerDe或者使用自帶的SerDe。若是沒有指定的ROW FORMAT或者ROW FORMAT DELIMITED,將會使用自帶的SerDe;在建立表時,用戶還須要爲表指定列,同時也會指定
自定義的SerDe。Hive經過SerDe肯定表的具體的列的數據。Serde是 Serializer/Deserializer的簡寫。hive使用Serde進行行對象的序列與反序列化。
一條簡單的建表語句以下:
hive> CREATE TABLE gripe(foo INT, bar STRING);
Like:容許用戶複製現有的表結構,可是不復制數據。例如:
hive>CREATE TABLE empty_key_value_store LIKE key_value_store
另外還能夠經過CREATE TABLE AS SELECT的方式來建立表,例如:
hive>CREATE TABLE new_key_value_store
ROW FORMAT SERDE "org.apache.Hadoop.hive.serde2.columnar.ColumnarSerDe" STORED AS RCFile
AS
SELECT (key % 1024) new_key , concat(key, value) key_value_pair
FROM key_value_store
SORT BY new_key, key_value_pair;
修改表名的語法以下:
hive> ALTER TABLE old_table_name RENAME TO new_table_name;
修改列名的語法以下:
hive>ALTER TABLE table_name CHANGE [COLUMN] old_col_name new_col_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
上述語法容許改變列名、數據類型、註釋、列位置或者它們的任意組合。建表後若是須要增長一列,則使用以下語法:
hive>ALTER TABLE gripe ADD COLUMNS (new_col INT COMMENT 'new col comment');
DROP TABLE 語句用於刪除表的數據和元數據。對應外部表,只刪除Metastore中的元數據,而外部數據保存不動,例如:
drop table my_table;
若是隻想刪除表數據,保留表結構,跟MYSQL相似,使用TRUNCATE語句。
TRUNCATE TABLE my_table;
一、向表中加載數據
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INFO TABLE tablename [PARTITION(partcol1 = val1, partcol2 = val2, . . .)]
Load操做只是單純的複製/移動操做,將數據 文件移動到Hive表對應的位置,filepath能夠是相對路徑,例如project/data1, 也能夠是絕對路徑,例如:/user/hive/project/data1, 或是包含模式的完整URI,例如:
hdfs://namenode:9000/user/hive/project/data1。
相對路徑實例以下:
hive> LOAD DATA LOCAL INPATH './examples/files/kv1.txt' OVERWRITE INTO TABLE gripe;
二、將查詢結果插入Hive表
將查詢結果寫入HDFS文件系統。
a、基本模式:
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1 = val1, partcol2 = val2, . . .)]
select_statements FROM from_statement
b、多插入模式:
INSERT OVERWRITE TABLE tablename1
[PARTITION (partcol1 = val1, partcol2 = val2, . . . )]
select_statement1
[ INSERT OVERWRITE TABLE tablename2 [PARTITION . . . ] select_statement2] . . .
c、自動分區模式:
INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] . . . )
select_statement From from_statement
Hive中的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]
ALL和DISTINCT:選項區分對重複記錄的處理。默認是ALL,表示查詢全部記錄。DISTINCT表示去掉重複記錄。
WHERE條件:相似於傳統的SQL的where條件,支持 AND 、OR、BETWEEN、IN、NOT IN等。
ORDER BY與SORT BY的不一樣:ORDER BY指全局排序,只有一個Reduce任務,而SORT BY只在本機作排序。
LIMIT:能夠限制查詢的記錄條數,例如:SELECT * FROM t1 LIMIT 5, 也能夠實現Top k查詢,好比下面的查詢語句能夠查詢銷售記錄最多的5個銷售表明:
SET mapred.reduce.tasks = 1
SELECT * FROM test SORT BY amount DESC LIMIT 5
REGEX Column Specification:select 語句可使用正則表達式作列選擇,下面的語句查詢除了ds和hr以外的全部列
SELECT '(ds|hr)?+.+' FROM test
二、join表
Hive中join表的語言以下:
join_table:
table_reference [INNER] JOIN table_factor [join_condition]
| table_reference {LEFT|RIGHT|FULL} [OUTER] JOIN table_reference join_condition
| table_reference LEFT SEMI JOIN table_reference join_condition
|table_reference CROSS JOIN table_reference [join_condition] (as of Hive 0.10)
table_reference:
table_factor
| join_table
table_factor:
tbl_name [alias]
| table_subquery alias
| (table_references)
join_confition:
On expression
對Hive中表Join操做的說明以及注意事項以下:
一、Hive只支持等值鏈接、外鏈接和左半鏈接(left semi join),Hive 不支持全部的非等值鏈接,由於非等值鏈接很難轉化到map/reduce任務(從2.2.0版本後開始支持非等值鏈接)。
二、能夠鏈接2個以上的表,例如:
SELECT a.val, b.val, c.val FROM a JOIN b on (a.key = b.key1) JOIN c on (c.key = b .key2)
三、若是鏈接中多個表的join key是同一個,則鏈接會轉化爲單個Map/Reduce任務,例如:
SELECT a.val, b.val, c.val FROM a JOIN b on (a.key = b.key1) JOIN c on (c.key = b .key1)
四、join時大表放在最後。這是由於每次Map/Reduce任務的邏輯是這樣的:Reduce會緩存join序列中除最後一個表以外的全部表的記錄,再經過最後一個表將將結果序列化文件系統,所以在實踐中,應該把最大的那個表寫在最後。
五、若是想限制join的輸出,應該在where子句中寫過濾條件,或是在join子句中寫,可是表分區的狀況很容易混淆,好比下面的第一個SQL語句所示,若是d表中找不到對應c表的記錄,d表的全部列都會列出NULL,包括ds列,
也就是說,join會過濾d表中不能找到 c表join key 的全部記錄。這樣,LEFT OUTER 就使得查詢結果與WHERE子句無關,解決辦法是在join時指定分區(以下面的第二個SQL語句)。
//第一個SQL語句
SELECT c.val, d.val FROM c LEFT OUTER JOIN d ON (c.key = d.key) where c.ds = '2010-08-08' AND d.ds ='2010-08-08'
//第一個SQL語句
SELECT c.val, d.val FROM c LEFT OUTER JOIN d ON (c.key = d.key AND c.ds = '2010-08-08' AND d.ds ='2010-08-08')
六、LEFT SEMI JOIN是IN/EXISTS子查詢的一種更高效的實現。其限制是:JOIN子句中右邊的表只能在On子句中設置過濾條件,在WHERE子句、SELECT子句、或其餘地方過濾都不行。
SELECT a.key, a.value FROM a WHERE a.key in (SELECT b.key FROM b);
能夠被重寫爲:SELECT a.key, a.value FROM a LEFT SEMI JOIN b on (a.key = b.key)
參考資料:《離線和實時大數據開發實戰》