1.HIVE結構node
Hive 是創建在 Hadoop 上的數據倉庫基礎構架。它提供了一系列的工具,能夠用來進行數據提取轉化加載(ETL),這是一種能夠存儲、查詢和分析存儲在 Hadoop 中的大規模數據的機制。Hive 定義了簡單的類 SQL 查詢語言,稱爲 QL,它容許熟悉 SQL 的用戶查詢數據。同時,這個語言也容許熟悉 MapReduce 開發者的開發自定義的 mapper 和 reducer 來處理內建的 mapper 和 reducer 沒法完成的複雜的分析工做。
python
1.1HIVE架構mysql
Hive 的結構能夠分爲如下幾部分:正則表達式
用戶接口:包括 CLI, Client, WUI sql
元數據存儲。一般是存儲在關係數據庫如 mysql, derby 中 數據庫
解釋器、編譯器、優化器、執行器 express
Hadoop:用 HDFS 進行存儲,利用 MapReduce 進行計算 apache
用戶接口主要有三個:CLI,Client 和 WUI。其中最經常使用的是 CLI,Cli 啓動的時候,會同時啓動一個 Hive 副本。Client 是 Hive 的客戶端,用戶鏈接至 Hive Server。在啓動 Client 模式的時候,須要指出 Hive Server 所在節點,而且在該節點啓動 Hive Server。 WUI 是經過瀏覽器訪問 Hive。 瀏覽器
Hive 將元數據存儲在數據庫中,如 mysql、derby。Hive 中的元數據包括表的名字,表的列和分區及其屬性,表的屬性(是否爲外部表等),表的數據所在目錄等。 緩存
解釋器、編譯器、優化器完成 HQL 查詢語句從詞法分析、語法分析、編譯、優化以及查詢計劃的生成。生成的查詢計劃存儲在 HDFS 中,並在隨後有 MapReduce 調用執行。
Hive 的數據存儲在 HDFS 中,大部分的查詢由 MapReduce 完成(包含 * 的查詢,好比 select * from tbl 不會生成 MapRedcue 任務)。
Hive 構建在 Hadoop 之上
HQL 中對查詢語句的解釋、優化、生成查詢計劃是由 Hive 完成的
全部的數據都是存儲在 Hadoop 中
查詢計劃被轉化爲 MapReduce 任務,在 Hadoop 中執行(有些查詢沒有 MR 任務,如:select * from table)
Hadoop和Hive都是用UTF-8編碼的
二、HIVE的數據存儲
首先,Hive 沒有專門的數據存儲格式,也沒有爲數據創建索引,用戶能夠很是自由的組織 Hive 中的表,只須要在建立表的時候告訴 Hive 數據中的列分隔符和行分隔符,Hive 就能夠解析數據。
其次,Hive 中全部的數據都存儲在 HDFS 中,Hive 中包含如下數據模型:Table,External Table,Partition,Bucket。
Hive 中的 Table 和數據庫中的 Table 在概念上是相似的,每個 Table 在 Hive 中都有一個相應的目錄存儲數據。例如,一個表 htduan,它在 HDFS 中的路徑爲:/ warehouse /htduan,其中,wh 是在 hive-site.xml 中由 ${hive.metastore.warehouse.dir} 指定的數據倉庫的目錄,全部的 Table 數據(不包括 External Table)都保存在這個目錄中。
Partition 對應於數據庫中的 Partition 列的密集索引,可是 Hive 中 Partition 的組織方式和數據庫中的很不相同。在 Hive 中,表中的一個 Partition 對應於表下的一個目錄,全部的 Partition 的數據都存儲在對應的目錄中。例如:htduan 表中包含 dt 和 city 兩個 Partition,則對應於 dt = 20100801, ctry = US 的 HDFS 子目錄爲:/ warehouse /htduan/dt=20100801/ctry=US;對應於 dt = 20100801, ctry = CA 的 HDFS 子目錄爲;/ warehouse /htduan/dt=20100801/ctry=CA
Buckets 對指定列計算 hash,根據 hash 值切分數據,目的是爲了並行,每個 Bucket 對應一個文件。將 user 列分散至 32 個 bucket,首先對 user 列的值計算 hash,對應 hash 值爲 0 的 HDFS 目錄爲:/ warehouse /htduan/dt =20100801/ctry=US/part-00000;hash 值爲 20 的 HDFS 目錄爲:/ warehouse /htduan/dt =20100801/ctry=US/part-00020
External Table 指向已經在 HDFS 中存在的數據,能夠建立 Partition。它和 Table 在元數據的組織上是相同的,而實際數據的存儲則有較大的差別。
Table 的建立過程和數據加載過程(這兩個過程能夠在同一個語句中完成),在加載數據的過程當中,實際數據會被移動到數據倉庫目錄中;以後對數據對訪問將會直接在數據倉庫目錄中完成。刪除表時,表中的數據和元數據將會被同時刪除。
External Table 只有一個過程,加載數據和建立表同時完成(CREATE EXTERNAL TABLE ……LOCATION),實際數據是存儲在 LOCATION 後面指定的 HDFS 路徑中,並不會移動到數據倉庫目錄中。當刪除一個 External Table 時,僅刪除
3.HIVE基本操做
它與關係型數據庫的SQL 略有不一樣,但支持了絕大多數的語句如DDL、DML 以及常見的聚合函數、鏈接查詢、條件查詢。HIVE不適合用於聯機(online)事務處理,也不提供實時查詢功能。它最適合應用在基於大量不可變數據的批處理做業。
HIVE的特色:可伸縮(在Hadoop的集羣上動態的添加設備),可擴展,容錯,輸入格式的鬆散耦合。
3.一、DDL 操做
DDL
建表
刪除表
修改表結構
建立/刪除視圖
建立數據庫
顯示命令
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 EXIST 選項來忽略這個異常
EXTERNAL 關鍵字可讓用戶建立一個外部表,在建表的同時指定一個指向實際數據的路徑(LOCATION)
LIKE 容許用戶複製現有的表結構,可是不復制數據
COMMENT能夠爲表與字段增長描述
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 肯定表的具體的列的數據。
STORED AS
SEQUENCEFILE
| TEXTFILE
| RCFILE
| INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname
若是文件數據是純文本,可使用 STORED AS TEXTFILE。若是數據須要壓縮,使用 STORED AS SEQUENCE 。
hive> CREATE TABLE pokes (foo INT, bar STRING);
CREATE EXTERNAL TABLE page_view(viewTime INT, userid BIGINT,
page_url STRING, referrer_url STRING,
ip STRING COMMENT 'IP Address of the User',
country STRING COMMENT 'country of origination')
COMMENT 'This is the staging page view table'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\054'
STORED AS TEXTFILE
LOCATION '<hdfs_location>';
CREATE TABLE par_table(viewTime INT, userid BIGINT,
page_url STRING, referrer_url STRING,
ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(date STRING, pos STRING)
ROW FORMAT DELIMITED ‘\t’
FIELDS TERMINATED BY '\n'
STORED AS SEQUENCEFILE;
CREATE TABLE par_table(viewTime INT, userid BIGINT,
page_url STRING, referrer_url STRING,
ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(date STRING, pos STRING)
CLUSTERED BY(userid) SORTED BY(viewTime) INTO 32 BUCKETS
ROW FORMAT DELIMITED ‘\t’
FIELDS TERMINATED BY '\n'
STORED AS SEQUENCEFILE;
hive> CREATE TABLE invites (foo INT, bar STRING) PARTITIONED BY (ds STRING);
CREATE TABLE empty_key_value_store
LIKE key_value_store;
例子
create table user_info (user_id int, cid string, ckid string, username string)
row format delimited fields terminated by '\t' lines terminated by '\n';
導入數據表的數據格式是:字段之間是tab鍵分割,行之間是斷行。
及要咱們的文件內容格式:
100636 100890 c5c86f4cddc15eb7 yyyvybtvt
100612 100865 97cc70d411c18b6f gyvcycy
100078 100087 ecd6026a15ffddf5 qa000100
hive> SHOW TABLES;
hive> SHOW TABLES '.*s';
增長分區、刪除分區
重命名錶
修改列的名字、類型、位置、註釋
增長/更新列
增長表的元數據信息
hive> ALTER TABLE pokes ADD COLUMNS (new_col INT);
hive> ALTER TABLE invites ADD COLUMNS (new_col2 INT COMMENT 'a comment');
hive> ALTER TABLE events RENAME TO 3koobecaf;
hive> DROP TABLE pokes;
增長
ALTER TABLE table_name ADD [IF NOT EXISTS] partition_spec [ LOCATION 'location1' ] partition_spec [ LOCATION 'location2' ] ...
partition_spec:
: PARTITION (partition_col = partition_col_value, partition_col = partiton_col_value, ...)
刪除
ALTER TABLE table_name DROP partition_spec, partition_spec,...
ALTER TABLE table_name RENAME TO new_table_name
ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
這個命令能夠容許改變列名、數據類型、註釋、列位置或者它們的任意組合
hive> ALTER TABLE pokes ADD COLUMNS (new_col INT);
hive> ALTER TABLE invites ADD COLUMNS (new_col2 INT COMMENT 'a comment');
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)
ADD是表明新增一字段,字段位置在全部列後面(partition列前)
REPLACE則是表示替換表中全部字段。
ALTER TABLE table_name SET TBLPROPERTIES table_properties table_properties:
:[property_name = property_value…..]
用戶能夠用這個命令向表中增長metadata
ALTER TABLE table_name SET FILEFORMAT file_format
ALTER TABLE table_name CLUSTERED BY(userid) SORTED BY(viewTime) INTO num_buckets BUCKETS
這個命令修改了表的物理存儲屬性
CREATE VIEW [IF NOT EXISTS] view_name [ (column_name [COMMENT column_comment], ...) ][COMMENT view_comment][TBLPROPERTIES (property_name = property_value, ...)] AS SELECT
增長視圖
若是沒有提供表名,視圖列的名字將由定義的SELECT表達式自動生成
若是修改基本表的屬性,視圖中不會體現,無效查詢將會失敗
視圖是隻讀的,不能用LOAD/INSERT/ALTER
DROP VIEW view_name
刪除視圖
CREATE DATABASE name
show tables;
show databases;
show partitions ;
show functions
describe extended table_name dot col_name
2. DML 操做:元數據存儲
hive不支持用insert語句一條一條的進行插入操做,也不支持update操做。數據是以load的方式加載到創建好的表中。數據一旦導入就不能夠修改。
DML包括:INSERT插入、UPDATE更新、DELETE刪除
向數據表內加載文件
將查詢結果插入到Hive表中
0.8新特性 insert into
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO 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 pokes;
加載的目標能夠是一個表或者分區。若是表包含分區,必須指定每個分區的分區名
filepath 能夠引用一個文件(這種狀況下,Hive 會將文件移動到表所對應的目錄中)或者是一個目錄(在這種狀況下,Hive 會將目錄中的全部文件移動至表所對應的目錄中)
LOCAL關鍵字
指定了LOCAL,即本地
load 命令會去查找本地文件系統中的 filepath。若是發現是相對路徑,則路徑會被解釋爲相對於當前用戶的當前路徑。用戶也能夠爲本地文件指定一個完整的 URI,好比:file:///user/hive/project/data1.
load 命令會將 filepath 中的文件複製到目標文件系統中。目標文件系統由表的位置屬性決定。被複制的數據文件移動到表的數據對應的位置
例如:加載本地數據,同時給定分區信息:
hive> LOAD DATA LOCAL INPATH './examples/files/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');
沒有指定LOCAL
若是 filepath 指向的是一個完整的 URI,hive 會直接使用這個 URI。 不然
若是沒有指定 schema 或者 authority,Hive 會使用在 hadoop 配置文件中定義的 schema 和 authority,fs.default.name 指定了 Namenode 的 URI
若是路徑不是絕對的,Hive 相對於 /user/ 進行解釋。 Hive 會將 filepath 中指定的文件內容移動到 table (或者 partition)所指定的路徑中
加載DFS數據 ,同時給定分區信息:
hive> LOAD DATA INPATH '/user/myname/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');
The above command will load data from an HDFS file/directory to the table. Note that loading data from HDFS will result in moving the file/directory. As a result, the operation is almost instantaneous.
指定了OVERWRITE
目標表(或者分區)中的內容(若是有)會被刪除,而後再將 filepath 指向的文件/目錄中的內容添加到表/分區中。
若是目標表(分區)已經有一個文件,而且文件名和 filepath 中的文件名衝突,那麼現有的文件會被新文件所替代。
將查詢結果插入Hive表
將查詢結果寫入HDFS文件系統
基本模式
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement
多插入模式
FROM from_statement
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1
[INSERT OVERWRITE TABLE tablename2 [PARTITION ...] select_statement2] ...
自動分區模式
INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 SELECT ... FROM ...
FROM from_statement
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1
[INSERT OVERWRITE [LOCAL] DIRECTORY directory2 select_statement2]
數據寫入文件系統時進行文本序列化,且每列用^A 來區分,\n換行
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement
3. DQL 操做:數據查詢SQL
SQL操做
基本的Select 操做
基於Partition的查詢
Join
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 ,0.9版本支持between
IN, NOT IN
不支持EXIST ,NOT EXIST
ORDER BY與SORT BY的不一樣
ORDER BY 全局排序,只有一個Reduce任務
SORT BY 只在本機作排序
Limit
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
hive> SELECT a.foo FROM invites a WHERE a.ds='<DATE>';
hive> INSERT OVERWRITE DIRECTORY '/tmp/hdfs_out' SELECT a.* FROM invites a WHERE a.ds='<DATE>';
hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/local_out' SELECT a.* FROM pokes a;
hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a;
hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a WHERE a.key < 100;
hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/reg_3' SELECT a.* FROM events a;
hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_4' select a.invites, a.pokes FROM profiles a;
hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT COUNT(1) FROM invites a WHERE a.ds='<DATE>';
hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT a.foo, a.bar FROM invites a;
hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/sum' SELECT SUM(a.pc) FROM pc1 a;
hive> FROM invites a INSERT OVERWRITE TABLE events SELECT a.bar, count(1) WHERE a.foo > 0 GROUP BY a.bar;
hive> INSERT OVERWRITE TABLE events SELECT a.bar, count(1) FROM invites a WHERE a.foo > 0 GROUP BY a.bar;
JOIN
hive> FROM pokes t1 JOIN invites t2 ON (t1.bar = t2.bar) INSERT OVERWRITE TABLE events SELECT t1.bar, t1.foo, t2.foo;
FROM src
INSERT OVERWRITE TABLE dest1 SELECT src.* WHERE src.key < 100
INSERT OVERWRITE TABLE dest2 SELECT src.key, src.value WHERE src.key >= 100 and src.key < 200
INSERT OVERWRITE TABLE dest3 PARTITION(ds='2008-04-08', hr='12') SELECT src.key WHERE src.key >= 200 and src.key < 300
INSERT OVERWRITE LOCAL DIRECTORY '/tmp/dest4.out' SELECT src.value WHERE src.key >= 300;
hive> FROM invites a INSERT OVERWRITE TABLE events SELECT TRANSFORM(a.foo, a.bar) AS (oof, rab) USING '/bin/cat' WHERE a.ds > '2008-08-09';
This streams the data in the map phase through the script /bin/cat (like hadoop streaming). Similarly - streaming can be used on the reduce side (please see the Hive Tutorial or examples)
通常 SELECT 查詢會掃描整個表,使用 PARTITIONED BY 子句建表,查詢就能夠利用分區剪枝(input pruning)的特性
Hive 當前的實現是,只有分區斷言出如今離 FROM 子句最近的那個WHERE 子句中,纔會啓用分區剪枝
Syntax
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
table_reference:
table_factor
| join_table
table_factor:
tbl_name [alias]
| table_subquery alias
| ( table_references )
join_condition:
ON equality_expression ( AND equality_expression )*
equality_expression:
expression = expression
Hive 只支持等值鏈接(equality joins)、外鏈接(outer joins)和(left semi joins)。Hive 不支持全部非等值的鏈接,由於非等值鏈接很是難轉化到 map/reduce 任務
LEFT,RIGHT和FULL OUTER關鍵字用於處理join中空記錄的狀況
LEFT SEMI JOIN 是 IN/EXISTS 子查詢的一種更高效的實現
join 時,每次 map/reduce 任務的邏輯是這樣的:reducer 會緩存 join 序列中除了最後一個表的全部表的記錄,再經過最後一個表將結果序列化到文件系統
實踐中,應該把最大的那個表寫在最後
join 查詢時,須要注意幾個關鍵點
只支持等值join
SELECT a.* FROM a JOIN b ON (a.id = b.id)
SELECT a.* FROM a JOIN b
ON (a.id = b.id AND a.department = b.department)
能夠 join 多於 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中多個表的 join key 是同一個,則 join 會被轉化爲單個 map/reduce 任務
LEFT,RIGHT和FULL OUTER
例子
SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key)
若是你想限制 join 的輸出,應該在 WHERE 子句中寫過濾條件——或是在 join 子句中寫
容易混淆的問題是表分區的狀況
SELECT c.val, d.val FROM c LEFT OUTER JOIN d ON (c.key=d.key)
WHERE a.ds='2010-07-07' AND b.ds='2010-07-07‘
若是 d 表中找不到對應 c 表的記錄,d 表的全部列都會列出 NULL,包括 ds 列。也就是說,join 會過濾 d 表中不能找到匹配 c 表 join key 的全部記錄。這樣的話,LEFT OUTER 就使得查詢結果與 WHERE 子句無關
解決辦法
SELECT c.val, d.val FROM c LEFT OUTER JOIN d
ON (c.key=d.key AND d.ds='2009-07-07' AND c.ds='2009-07-07')
LEFT SEMI JOIN
LEFT SEMI JOIN 的限制是, JOIN 子句中右邊的表只能在 ON 子句中設置過濾條件,在 WHERE 子句、SELECT 子句或其餘地方過濾都不行
SELECT a.key, a.value
FROM a
WHERE a.key in
(SELECT b.key
FROM B);
能夠被重寫爲:
SELECT a.key, a.val
FROM a LEFT SEMI JOIN b on (a.key = b.key)
UNION ALL
用來合併多個select的查詢結果,須要保證select中字段須一致
select_statement UNION ALL select_statement UNION ALL select_statement ...
4.從SQL到HiveQL應轉變的習慣
SQL中對兩表內聯能夠寫成:
select * from dual a,dual b where a.key = b.key;
Hive中應爲
select * from dual a join dual b on a.key = b.key;
而不是傳統的格式:
SELECT t1.a1 as c1, t2.b1 as c2FROM t1, t2 WHERE t1.a2 = t2.b2
分號是SQL語句結束標記,在HiveQL中也是,可是在HiveQL中,對分號的識別沒有那麼智慧,例如:
select concat(key,concat(';',key)) from dual;
但HiveQL在解析語句時提示:
FAILED: Parse Error: line 0:-1 mismatched input '<EOF>' expecting ) in function specification
解決的辦法是,使用分號的八進制的ASCII碼進行轉義,那麼上述語句應寫成:
select concat(key,concat('\073',key)) from dual;
SQL中null表明空值, 值得警戒的是, 在HiveQL中String類型的字段如果空(empty)字符串, 即長度爲0, 那麼對它進行IS NULL的判斷結果是False.
僅支持覆蓋重寫整個表,示例以下:
INSERT OVERWRITE TABLE t1
SELECT * FROM t2;
這樣的話,就不要很複雜的鎖機制來讀寫數據。
INSERT INTO syntax is only available starting in version 0.8。INSERT INTO就是在表或分區中追加數據。
如:
FROM (
MAP doctext USING 'python wc_mapper.py' AS (word, cnt)
FROM docs
CLUSTER BY word
) a
REDUCE word, cnt USING 'python wc_reduce.py';
--doctext: 是輸入
--word, cnt: 是map程序的輸出
--CLUSTER BY: 將wordhash後,又做爲reduce程序的輸入
而且map程序、reduce程序能夠單獨使用,如:
FROM (
FROM session_table
SELECT sessionid, tstamp, data
DISTRIBUTE BY sessionid SORT BY tstamp
) a
REDUCE sessionid, tstamp, data USING 'session_reducer.sh';
--DISTRIBUTE BY: 用於給reduce程序分配行數據
這樣能免除屢次掃描輸入表的開銷。
FROM t1
INSERT OVERWRITE TABLE t2
SELECT t3.c2, count(1)
FROM t3
WHERE t3.c1 <= 20
GROUP BY t3.c2
INSERT OVERWRITE DIRECTORY '/output_dir'
SELECT t3.c2, avg(t3.c1)
FROM t3
WHERE t3.c1 > 20 AND t3.c1 <= 30
GROUP BY t3.c2
INSERT OVERWRITE LOCAL DIRECTORY '/home/dir'
SELECT t3.c2, sum(t3.c1)
FROM t3
WHERE t3.c1 > 30
GROUP BY t3.c2;
5. 實際示例
CREATE TABLE u_data (
userid INT,
movieid INT,
rating INT,
unixtime STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '/t'
STORED AS TEXTFILE;
下載示例數據文件,並解壓縮
wget http://www.grouplens.org/system/files/ml-data.tar__0.gz
tar xvzf ml-data.tar__0.gz
LOAD DATA LOCAL INPATH 'ml-data/u.data'
OVERWRITE INTO TABLE u_data;
SELECT COUNT(1) FROM u_data;
建立一個 weekday_mapper.py: 文件,做爲數據按周進行分割
import sys
import datetime
for line in sys.stdin:
line = line.strip()
userid, movieid, rating, unixtime = line.split('/t')
weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()
print '/t'.join([userid, movieid, rating, str(weekday)])
//建立表,按分割符分割行中的字段值
CREATE TABLE u_data_new (
userid INT,
movieid INT,
rating INT,
weekday INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '/t';
//將python文件加載到系統
add FILE weekday_mapper.py;
INSERT OVERWRITE TABLE u_data_new
SELECT
TRANSFORM (userid, movieid, rating, unixtime)
USING 'python weekday_mapper.py'
AS (userid, movieid, rating, weekday)
FROM u_data;
SELECT weekday, COUNT(1)
FROM u_data_new
GROUP BY weekday;
將WEB日誌先用正則表達式進行組合,再按須要的條件進行組合輸入到表中
add jar ../build/contrib/hive_contrib.jar;
CREATE TABLE apachelog (host STRING,identity STRING,user STRING,time STRING,request STRING,status STRING,size STRING,referer STRING,agent STRING)ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'WITH SERDEPROPERTIES ("input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) (-|//[[^//]]*//]) ([^ /"]*|/"[^/"]*/") (-|[0-9]*) (-|[0-9]*)(?: ([^ /"]*|/"[^/"]*/") ([^ /"]*|/"[^/"]*/"))?","output.format.string" = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s")STORED AS TEXTFILE;