Hive的TRANSFORM
關鍵字提供了在SQL中調用自寫腳本的功能,適合實現Hive中沒有的功能又不想寫UDF的情況。例如,按日期統計每天出現的uid
數,通常用如下的SQL
SELECT date, count(uid)
FROM xxx
GROUP BY date
但是,如果我想在reduce階段對每天的uid
形成一個列表,進行排序並輸出,這在Hive中沒有現成的功能。那么,可以自寫腳本實現該功能,並用TRANSFORM
關鍵字調用
SELECT TRANSFORM(date, uid)
FROM xxx
CLUSTER BY date
這是一個類似streaming的功能,但是可以更方便的訪問Hive中的數據,也可以把SQL語句和自寫腳本整合在一起運行。
簡單分析官網上的一個例子
FROM (
FROM pv_users
SELECT TRANSFORM(pv_users.userid, pv_users.date)
USING 'map_script'
AS dt, uid
CLUSTER BY dt
) map_output
INSERT OVERWRITE TABLE pv_users_reduced
SELECT TRANSFORM(map_output.dt, map_output.uid)
USING 'reduce_script'
AS date, count;
這段代碼的大致工作流程描述如下:
map_script
作為mapper,reduce_script
作為reducer。將pv_users
表中的userid
, date
兩列作為mapper的輸入字段,處理后的輸出的前兩個字段分別命名為dt
, uid
,並按照dt
字段作partition和sort送給reduce階段處理。reducer的輸入字段為dt
和uid
,輸出處理后的前兩個字段,並命名為date
, count
,寫入到pv_users_reduced
表中。
這里有幾個細節:
- mapper和reducer用到的script可以是任何可執行文件。注意如果用到的是本地文件,應當在語句開始前用
ADD FILE
或ADD FILES
將文件加入進來 - mapper和reducer的輸入輸出都是以TAB為分隔符
- 如果
USING ‘script’
語句后面沒有AS
,則Hive默認script
的輸出中第一個TAB之前的字段為key,后面的部分全部為value。若指定了AS
,則嚴格按照AS
后面的字段數輸出,例如AS dt, uid
,則輸出前兩個字段並忽略后面的字段。此外,AS
語句可以指定數據類型,如AS (date STRING, count INT)
。默認都是string
類型。 CLUSTER BY
關鍵字是DISTRIBUTE BY
和SORT BY
的簡寫,這兩者可以認為對應與Hadoop的partition和sort過程。如果partition和sort的key是不同的,可以使用DISTRIBUTE BY
和SORT BY
分別指定。MAP
和REDUCE
關鍵字是SELECT TRANSFORM
關鍵字的別名,原文中給出了上面等價代碼
因此,原文中特別提醒,FROM ( FROM pv_users MAP pv_users.userid, pv_users.date USING 'map_script' AS dt, uid CLUSTER BY dt ) map_output INSERT OVERWRITE TABLE pv_users_reduced REDUCE map_output.dt, map_output.uid USING 'reduce_script' AS date, count;
MAP
並沒有強制產生一個map過程的作用,REDUCE
同理。只是為了閱讀更清晰。