文章目錄
- 目錄
- 前言:
- 1、Hive基本操作
- 1.1、DDL操作
- 1.2、DML操作
- 1.3、Hive Join
- 總結:
目錄
前言:
對于Hive來說最重要的一點就是能夠用Hql來進行數據分析。而Hql來處理數據比MapReduce方便很多(原理是一樣的,Hql底層轉化為MapReduce來處理數據)。而隨著技術的發展,編寫MapReduce程序來處理數據也許會被慢慢淘汰,而Hql仍會保留下來(原因:1、類SQL語法,學習成本比較低。2、大數據時代對數據開發的需求,需要有這樣的數據倉庫來支撐。)
1、Hive基本操作
1.1、DDL操作
1.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]
說明:
1、 CREATE TABLE 創建一個指定名字的表。如果相同名字的表已經存在,則拋出異常;用戶可以用 IF NOT EXISTS 選項來忽略這個異常。
2、 EXTERNAL關鍵字可以讓用戶創建一個外部表,在建表的同時指定一個指向實際數據的路徑(LOCATION),Hive 創建內部表時,會將數據移動到數據倉庫指向的路徑;若創建外部表,僅記錄數據所在的路徑,不對數據的位置做任何改變。在刪除表的時候,內部表的元數據和數據會被一起刪除,而外部表只刪除元數據,不刪除數據。
3、 LIKE 允許用戶復制現有的表結構,但是不復制數據。
4、
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, ...)]
用戶在建表的時候可以自定義 SerDe 或者使用自帶的 SerDe。如果沒有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,將會使用自帶的 SerDe。在建表的時候,用戶還需要為表指定列,用戶在指定表的列的同時也會指定自定義的 SerDe,Hive通過 SerDe 確定表的具體的列的數據。
5、
STORED AS
SEQUENCEFILE|TEXTFILE|RCFILE
如果文件數據是純文本,可以使用 STORED AS TEXTFILE。如果數據需要壓縮,使用 STORED AS SEQUENCEFILE。
6、CLUSTERED BY
對于每一個表(table)或者分區, Hive可以進一步組織成桶,也就是說桶是更為細粒度的數據范圍劃分。Hive也是 針對某一列進行桶的組織。Hive采用對列值哈希,然后除以桶的個數求余的方式決定該條記錄存放在哪個桶當中。
把表(或者分區)組織成桶(Bucket)有兩個理由:
**(1)獲得更高的查詢處理效率。**桶為表加上了額外的結構,Hive 在處理有些查詢時能利用這個結構。具體而言,連接兩個在(包含連接列的)相同列上劃分了桶的表,可以使用 Map 端連接 (Map-side join)高效的實現。比如JOIN操作。對于JOIN操作兩個表有一個相同的列,如果對這兩個表都進行了桶操作。那么將保存相同列值的桶進行JOIN操作就可以,可以大大較少JOIN的數據量。
**(2)使取樣(sampling)更高效。**在處理大規模數據集時,在開發和修改查詢的階段,如果能在數據集的一小部分數據上試運行查詢,會帶來很多方便。
具體實例
1、 創建內部表mytable。
2、 創建外部表pageview。
3、 創建分區表invites。
4、 創建帶桶的表student。
1.1.2、修改表
增加/刪除分區
語法結構
ALTER TABLE table_name **ADD** [IF NOT EXISTS] partition_spec [ LOCATION 'location1' ] partition_spec [ LOCATION 'location2' ] ...
具體實例
alter table student_p add partition(part='a') partition(part='b');
重命名表
ALTER TABLE table_name **RENAME TO** new_table_name
具體實例:
增加/更新列
語法結構
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)
注:ADD是代表新增一字段,字段位置在所有列后面(partition列前),REPLACE則是表示替換表中所有字段。
1.1.3、顯示命令
show tables
show databases
show partitions
show functions
desc t_name;
desc extended t_name;
desc formatted table_name;
1.2、DML操作
1.2.1、Load
語法結構
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO
TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
說明:
1、 Load 操作只是單純的復制/移動操作,將數據文件移動到 Hive 表對應的位置。
2、 filepath:
相對路徑,例如:project/data1
絕對路徑,例如:/user/hive/project/data1
包含模式的完整 URI,列如:
hdfs://namenode:9000/user/hive/project/data1
3、 LOCAL關鍵字
如果指定了 LOCAL, load 命令會去查找本地文件系統中的 filepath。
如果沒有指定 LOCAL 關鍵字,則根據inpath中的uri[M1] 查找文件
4、 OVERWRITE 關鍵字
如果使用了 OVERWRITE 關鍵字,則目標表(或者分區)中的內容會被刪除,然后再將 filepath 指向的文件/目錄中的內容添加到表/分區中。
如果目標表(分區)已經有一個文件,并且文件名和 filepath 中的文件名沖突,那么現有的文件會被新文件所替代。
具體實例
1、加載絕對路徑數據
1.2.2、Insert
將查詢結果插入Hive表
語法結構
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement
具體實例
1、基本模式插入。
導出表數據
語法結構
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 SELECT ... FROM ...
具體實例
1、導出文件到本地。
2、導出數據到HDFS。
1.2.3 SELECT
基本的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]
注:
1、order by 會對輸入做全局排序,因此只有一個reducer,會導致當輸入規模較大時,需要較長的計算時間。
2、sort by不是全局排序,其在數據進入reducer前完成排序。因此,如果用sort by進行排序,并且設置mapred.reduce.tasks>1,則sort by只保證每個reducer的輸出有序,不保證全局有序。
3、distribute by根據distribute by指定的內容將數據分到同一個reducer。
4、Cluster by 除了具有Distribute by的功能外,還會對該字段進行排序。因此,常常認為cluster by = distribute by + sort by
分桶的作用:最大的作用是提高join的效率。
具體實例
1、查詢學生信息按年齡,降序排序。
1.3、Hive Join
語法結構
join_table:table_reference 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
,因為非等值連接非常難轉化到 map/reduce 任務。
另外,Hive 支持多于 2 個表的連接。
寫 join 查詢時,需要注意幾個關鍵點:
1、只支持等值join。
例如:
SELECT a.* FROM a JOIN b ON (a.id = b.id)SELECT a.* FROM a JOIN bON (a.id = b.id AND a.department = b.department)
是正確的,然而:
SELECT a.* FROM a JOIN b ON (a.id>b.id)
是錯誤的。
2、可以 join 多于 2 個表。
例如
SELECT a.val, b.val, c.val FROM a JOIN bON (a.key = b.key1) JOIN c ON (c.key = b.key2)
如果join中多個表的 join key 是同一個,則 join 會被轉化為單個 map/reduce 任務,例如:
SELECT a.val, b.val, c.val FROM a JOIN bON (a.key = b.key1) JOIN cON (c.key = b.key1)
被轉化為單個 map/reduce 任務,因為 join 中只使用了 b.key1 作為 join key。
SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1)JOIN c ON (c.key = b.key2)
而這一 join 被轉化為 2 個 map/reduce 任務。因為 b.key1 用于第一次 join 條件,而 b.key2 用于第二次 join。
具體實例
準備數據
表a
1,a
2,b
3,c
4,d
7,y
8,u
表b
2,bb
3,cc
7,yy
9,pp
實驗:
**inner join**
select * from a inner join b on a.id=b.id;
+-------+---------+-------+---------+--+
| a.id | a.name | b.id | b.name |
+-------+---------+-------+---------+--+
| 2 | b | 2 | bb |
| 3 | c | 3 | cc |
| 7 | y | 7 | yy |
+-------+---------+-------+---------+--+**outer join** 除了符合條件的數據外,還顯示主表存在,附表為NULL的數據。
select * from a outer join b on a.id=b.id;
+-------+---------+-------+---------+--+
| a.id | a.name | b.id | b.name |
+-------+---------+-------+---------+--+
| 1 | a | NULL | NULL |
| 2 | b | 2 | bb |
| 3 | c | 3 | cc |
| 4 | d | NULL | NULL |
| 7 | y | 7 | yy |
| 8 | u | NULL | NULL |**left join**(Left、right指的是以那邊的數據來作為基本數據來添加另一張表的數據)
select * from a left join b on a.id=b.id;
+-------+---------+-------+---------+--+
| a.id | a.name | b.id | b.name |
+-------+---------+-------+---------+--+
| 1 | a | NULL | NULL |
| 2 | b | 2 | bb |
| 3 | c | 3 | cc |
| 4 | d | NULL | NULL |
| 7 | y | 7 | yy |
| 8 | u | NULL | NULL |
+-------+---------+-------+---------+--+**left semi join**
把a和b都有的屬性羅列出來
select * from a **left semi join** b on a.id = b.id;
+-------+---------+--+
| a.id | a.name |
+-------+---------+--+
| 2 | b |
| 3 | c |
| 7 | y |
+-------+---------+--+
以上是Hive的一些基本操作,除此之外還有以下一些操作需要掌握:
保存select查詢結果的幾種方式:
1、將查詢結果保存到一張新的hive表中
create table t_tmp
as
select * from t_p;2、將查詢結果保存到一張已經存在的hive表中
insert into table t_tmp
select * from t_p;3、將查詢結果保存到指定的文件目錄(可以是本地,也可以是hdfs)
insert overwrite local directory '/home/hadoop/test'
select * from t_p;insert overwrite directory '/aaa/test'
select * from t_p;**##設置變量,設置分桶為true, 設置reduce數量是分桶的數量個數**
set hive.enforce.bucketing = true;
set mapreduce.job.reduces=4;
總結:
如果你掌握了以上一些常用的基本操作指令并能根據需求寫一些常用的分析語句,那么恭喜你已經和博主一樣進化為“小菜鳥”。接下來如果想把Hive玩熟,你除了要知道Hive中常用的內置函數外,還要能夠根據需求寫一些UDF,最后你還需要理解每條Hql執行后要轉化為什么樣的MapReduce程序,以此來提高你查詢的效率。以上是關于Hive基本操作的總結,目前就想到了這些,后續會接著補充,歡迎各位網友指點。