pig入门
Pig是一種操作大規(guī)模數(shù)據(jù)集的腳本語言,是在HDFS和MapReduce之上的數(shù)據(jù)流處理語言,將數(shù)據(jù)流翻譯成多個MR函數(shù)。
?
Pig包括兩部分:
PigLatin:用于描述數(shù)據(jù)流的語言
用于運行pig Latin程序的執(zhí)行環(huán)境
?
PigLatin程序有一系列的operation和transformation組成,每個操作或變換對屬于進行數(shù)據(jù)處理,將這些操作轉(zhuǎn)換為一系列的MapReduce作業(yè)。
Pig不適合所有的數(shù)據(jù)處理任務(wù),如果只想查詢大數(shù)據(jù)集中的一小部分?jǐn)?shù)據(jù),pig的實現(xiàn)不是很好,因為它要掃描整個數(shù)據(jù)集或絕大部分
?
1.Pig運行
1)pig腳本(將程序?qū)懭?/span>.pig文件中
2)Grunt(運行Pig命令的交互式shell環(huán)境
3)嵌入方式
?
pig與數(shù)據(jù)庫的比較:
1)pig是數(shù)據(jù)流編程語言,而SQL是一種描述性編程語言,Pig相當(dāng)于輸入的一步步操作,其中每一步都是對數(shù)據(jù)的簡單的變換
2)RDBMS把數(shù)據(jù)存儲在嚴(yán)格定義了模式的表內(nèi),但pig對數(shù)據(jù)的要求更寬松,可以在運行時定義模式,而且是可選的
3)pig對復(fù)雜、嵌套數(shù)據(jù)結(jié)構(gòu)支持更好
4)Pig不支持事務(wù)和索引,也不支持隨機度和幾十毫秒級別的數(shù)據(jù)查詢,它是針對數(shù)據(jù)批量處理的
5)Hive是結(jié)余Pig和RDBMS的系統(tǒng),Hive以HDFS為存儲,但是查詢語言是基于sql的,而且hive要求所有數(shù)據(jù)必須存儲于表中,
表必須有模式,而模式由hive管理,但hive允許為預(yù)先存在HDFS上的數(shù)據(jù)關(guān)聯(lián)一個模式,因此數(shù)據(jù)加載步驟是可選的
?
2.Pig Latin
程序由一系列的語句構(gòu)成,操作和命令是大小寫無關(guān)的,但是別名和函數(shù)名是大小寫敏感的
pig處理多行語句時,在整理程序邏輯計劃沒有構(gòu)造完畢前,pig并不處理數(shù)據(jù)。
?
關(guān)系操作
1)加載與存儲
| Load | 將數(shù)據(jù)從外部文件或其他存儲中加載數(shù)據(jù),存入關(guān)系 |
| Store | 將一個關(guān)系存放在文件系統(tǒng)或其他存儲中 |
| Dump | 將關(guān)系打印在控制臺 |
?
2)過濾
| Filter | 從關(guān)系中刪除不需要的行 |
| Distinct | 刪除 重復(fù)行 |
| FOREACH …?????? GENERATE | 對于集合的每個元素,生成或刪除字段 |
| STREAM | 使用外部程序?qū)﹃P(guān)系進行變換 |
| SAMPLE | 從關(guān)系中隨機取樣 |
?
3)分組與連接
| Join | 連接 |
| Cogroup | 在兩個或多個關(guān)系中分組 |
| Group | 在一個關(guān)系中對數(shù)據(jù)進行分組 |
| CROSS | 獲取兩個或更多關(guān)系的乘積 |
?
4)排序
| ORDER | 根據(jù)一個或多個字段進行排序 |
| Limit | 限制關(guān)系的元組個數(shù) |
?
5)合并與分割
| UNION | 合并關(guān)系 |
| SPLIT | 把某個關(guān)系切分成兩個或多個關(guān)系 |
?
6)Pig Latin的診斷操作
| ?操作? | 描述 |
| DESCRIBE? | 打印關(guān)系的模式 |
| EXPLAIN | 打印邏輯和物理計劃 |
| ILLUSTRATE | 使用生成的輸入子集顯示邏輯計劃的試運行結(jié)果 |
?
7)Pig Latin UDF語句
| REGISTER? | 在Pig運行時環(huán)境中注冊一個JAR文件 |
| DEFINE???? | 為UDF、流式腳本或命令規(guī)范新建別名 |
?
8)Pig Latin命令類型
| ?kill?? | 中止某個MapReduce任務(wù) |
| exec???????? | 在一個新的Grunt shell程序中以批處理模式運行一個腳本 |
| ?run?? | 在當(dāng)前Grunt外殼程序中運行程序 |
| ?quit????? | 退出解釋器 |
| ?set????? | 設(shè)置Pig選項 |
?
9)Pig Latin表達(dá)式
?
| 類型 | ???表達(dá)式?? | ?描述??????????? | ?示例 |
| 字段???????????????? | $n????????????????? | 第n個字段?????? | $0 |
| 字段???????????? | f??????????????? | 字段名f????????????????? | ?year |
| 投影?????????? | c.$n,?????? | c.f?在關(guān)系、包或元組中的字段?? | ?records.$0, records.year |
| Map查找?????????? | m#k????????? | 在映射m中鍵k對應(yīng)的值?????? | items’Coat’ |
| 類型轉(zhuǎn)換?????? | (t)f??????????? | 將字段t轉(zhuǎn)換成f類型?????????????????? | (int)year |
| 函數(shù)型平面化? | ?fn(f1, f2,?…)??????????? | 在字段上應(yīng)用函數(shù)????????????? | fn isGood(quality) |
?????????????????????????FLATTEN(f)?????????從包和元組中去除嵌套??????????????????flatten(group)
?其它的表達(dá)式,如算術(shù)、條件、比較和布爾型類似其它語言,不詳述.
?
10)Pig Latin類型
?
數(shù)據(jù)類型包括int (32位有符號整數(shù)), long(64位有符號整數(shù)), float(32位浮點數(shù)), double(64位浮點數(shù)),
chararray(UTF16格式的字符數(shù)組),Bytearray(字節(jié)數(shù)組), tuple(元組), bag(包), map(鍵值對).
?
tuple:(1,‘hello’)???????? //任何類型的字段序列
?bag: {(1,?‘hello’), (2)}???//元組的無序多重集合(允許重復(fù)元組)
?map: [‘a(chǎn)’?‘hello’]?????????//一組鍵值對,鍵必須是字符數(shù)組
?
關(guān)系和包在概念上是相同的,但是有細(xì)微差別。關(guān)系是頂層構(gòu)造結(jié)構(gòu),只能從上表中的關(guān)系操作中創(chuàng)建關(guān)系,包必須在某個關(guān)系中。
舉例:
?
A = {(1, 2), (3,4)}?????? //錯,使用load語句從文件中加載數(shù)據(jù)
?
B =A.$0??????????????????//錯,?B = foreach A generate $0;
?
11)模式
Pig的一個關(guān)系可以關(guān)聯(lián)一個模式,模式為關(guān)系的字段指定名稱和類型數(shù)據(jù)庫要求數(shù)據(jù)加載前必須先聲明模式截然不同,Pig設(shè)計的目的是用于分析不包含數(shù)據(jù)類型信息的純文本輸入文件的。但是盡量定義模式,會讓程序運行地更高效。
?
缺點:在查詢中聲明模式的方式是靈活的,但不利于模式重用。每個查詢中維護重復(fù)出現(xiàn)的模式會很困難。處理這一問題的辦法是寫自己的加載函數(shù)來封裝模式
?
SQL數(shù)據(jù)庫在加載數(shù)據(jù)時,會強制檢查表模式中的約束。在pig中,如果一個值無法被強制轉(zhuǎn)換為模式中申明的類型,pig會用空值null代替,
grunt>good_records = filter records by temperatureis not null;
?另一種技巧是使用SPLIT操作把數(shù)據(jù)劃分成好和壞兩個關(guān)系,然后在分別進行分析:
?grunt> split records into good_records iftemperature is not null,
??????????????????????????bad_records if temperature is null;
?grunt> dump good_records;
?
在pig中不用為數(shù)據(jù)流中的每個新產(chǎn)生的關(guān)系生命模式。大多數(shù)情況下,pig能根據(jù)關(guān)系操作的輸入關(guān)系的模式來確定輸出結(jié)果的模式
有些操作不改變模式,如limit,而Union回自動生成新的模式
?
如果要重新定義一個關(guān)系的模式,可以使用帶as語句的FOREACH …GENERATE操作來定義輸入關(guān)系的一部分或全部字段模式
?
12)函數(shù)
Pig的函數(shù)分為計算函數(shù),過濾函數(shù),加載函數(shù)和存儲函數(shù)
- 計算函數(shù):AVG, COUNT, CONCAT, COUNTSTAR, DIFF, MAX, MIN, SIZE, SUM, TOKENIZE
- 過濾函數(shù):IsEmpty
- 加載/存儲函數(shù):PigStorage, BinStorage, BinaryStorage, TextLoader, PigDump
用戶自定義函數(shù)
public abstract classEvalFunc<T>
REGISTERpig-examples.jar;
DEFINE isGoodorg.hadoopbook.pig.IsGoodQuality();
?
13)數(shù)據(jù)處理操作
加載和存儲數(shù)據(jù):store A into 'out' using pigStore(':');//將元祖存儲為以冒號為分割的純文本
連接:
C = join A by $0, B by $1; //?默認(rèn)為內(nèi)連接,將A的第一個字段和B的第二個字段連接,輸出匹配的字段
?//?連接后新關(guān)系的字段為輸入關(guān)系的字段和
?C = join A by $0, B by $1using?“replicated”; //?分段復(fù)制鏈接,B表中的數(shù)據(jù)將會放在內(nèi)存中
?C= join A by $0 left outer, Bby $1;? //?左外連接,左邊的沒有匹配項也輸出
?
Cogroup?多關(guān)系分組
?類似于Join,但默認(rèn)是外連接,連接鍵為第一個字段,第二個字段為匹配的第一個關(guān)系中的所有元組的包,第三個字段為第二個表中匹配的所有元組的包。
示例如下:
?D = COGROUP A by $0, B by $1;//?新的關(guān)系的元組個數(shù)為連接鍵的并集(去除重復(fù));
?D= COGROUP A by $0 inner, B by $1inner; //?新關(guān)系的元組個數(shù)是連接鍵取交集的個數(shù)(只輸出匹配的)。每個元組中的第二個和第三個字段都是一個包含一個元組的包
?COGROUP,inner和flatten組合使用相當(dāng)于實現(xiàn)了內(nèi)連接:
?G = COGROUP A by $0 innner, B by $1 inner;
?H = foreach G generate flatten($1), flatten($2)
?// H和join A by $0, Bby $1相同
?
Group?分組
?B = group A by $0; //?第一個字段為group字段,第二個字段為一個包,包含元組的其它字段
?B = group A by size($1);//?長度為第一個字段,第二個字段為一個包,包含所有長度為第一個字段的元組
?C = group A all; //?只有一行,第一個字段為all,第二個字段為A中所有元組的包
?D = group A any; //?對關(guān)系中的元組隨機分組,對取樣非常有用
?
排序數(shù)據(jù)
Pig按什么順序來處理關(guān)系的行是不確定的,只能在輸出前排序。
?B = order A by $0, $1 DESC;
?C = Limit B 2;
?
組合和切分?jǐn)?shù)據(jù)
?Union可以將幾個關(guān)系合在一起,即所有元組的集合,當(dāng)關(guān)系的模式不匹配時,新關(guān)系就沒有模式。
?C = union A, B;
?Split?可以將一個關(guān)系的元組按某種條件分成幾個子集。
?Split A into B if $0 is null, C if $0 is notnull;
?
參數(shù)替換:在pig語句中使用$加變量名的方式使用外部定義的變量值,在運行時可以通過"-param input=”設(shè)置變量的值,
或者通過"-param_file?”來指定參數(shù)文件。
?
動態(tài)參數(shù):很多Unix shell用反引號引用的命令來替換實際值,如`date?“+%Y-%m-%d”?`會按規(guī)定格式輸出日期。
這個可以放在-param或參數(shù)文件中來動態(tài)得到一個值
?
?
?
3.各種sql在pig中的實現(xiàn)
我這里以Mysql 5.1.x為例,Pig的版本是0.8
?同時我將數(shù)據(jù)放在了兩個文件,存放在/tmp/data_file_1和/tmp/data_file_2中.文件內(nèi)容如下:
?
tmp_file_1:
Txt代碼?
| User | Age | isMale |
| zhangsan? | 23? | 1? |
| lisi?? | 24 | 1? |
| wangmazi? | 30? | 1? |
| meinv? | 18 | 0? |
| dama??? | 55? | 0? |
?
tmp_file_2:
Txt代碼?
| Age | options |
| 1??? | a |
| 23??? | bb |
| 50? | ccc |
| 30? | dddd |
| 66? | eeeee? |
?
1.從文件導(dǎo)入數(shù)據(jù)
??? 1)Mysql (Mysql需要先創(chuàng)建表).
??????? CREATETABLE TMP_TABLE(USER VARCHAR(32),AGE INT,IS_MALE BOOLEAN);
???????CREATE TABLE TMP_TABLE_2(AGE INT,OPTIONS VARCHAR(50));?? --?用于Join
??????? LOAD DATALOCAL INFILE '/tmp/data_file_1'? INTO TABLE TMP_TABLE ;
??????? LOAD DATALOCAL INFILE '/tmp/data_file_2'? INTO TABLE TMP_TABLE_2;
??? 2)Pig
????????tmp_table = LOAD '/tmp/data_file_1' USING PigStorage('\t') AS (user:chararray,age:int,is_male:int);
????????tmp_table_2= LOAD '/tmp/data_file_2' USING PigStorage('\t') AS(age:int,options:chararray);
?2.查詢整張表
??? 1)Mysql
?????? SELECT * FROMTMP_TABLE;
??? 2)Pig
?????? DUMP tmp_table;
?3.?查詢前50行
??? 1)Mysql
?????? SELECT * FROMTMP_TABLE LIMIT 50;
??? 2)Pig
???????tmp_table_limit = LIMIT tmp_table 50;
??????? DUMPtmp_table_limit;
4.查詢某些列
??? 1)Mysql
??????? SELECTUSER FROM TMP_TABLE;
??? 2)Pig
???????tmp_table_user = FOREACH tmp_table GENERATE user;
??????? DUMPtmp_table_user;
?5.?給列取別名
???? 1)Mysql
??????? SELECTUSER AS USER_NAME,AGE AS USER_AGE FROM TMP_TABLE;
???? 2)Pig
???????tmp_table_column_alias = FOREACH tmp_table GENERATE user AS user_name,age ASuser_age;
??????? DUMPtmp_table_column_alias;
??6.排序
???? 1)Mysql
??????? SELECT *FROM TMP_TABLE ORDER BY AGE;
???? 2)Pig
????????tmp_table_order = ORDER tmp_table BY age ASC;
???????? DUMPtmp_table_order;
??7.條件查詢
???? 1)Mysql
????????SELECT * FROM TMP_TABLE WHERE AGE>20;
???? 2) Pig
????????tmp_table_where = FILTER tmp_table by age > 20;
???????? DUMPtmp_table_where;
??8.內(nèi)連接Inner Join
???? 1)Mysql
??????? SELECT *FROM TMP_TABLE A JOIN TMP_TABLE_2 B ON A.AGE=B.AGE;
???? 2)Pig
????????tmp_table_inner_join = JOIN tmp_table BY age,tmp_table_2 BY age;
???????? DUMPtmp_table_inner_join;
?9.左連接Left? Join
??? 1)Mysql
??????? SELECT *FROM TMP_TABLE A LEFT JOIN TMP_TABLE_2 B ON A.AGE=B.AGE;
??? 2)Pig
??????tmp_table_left_join = JOIN tmp_table BY age LEFT OUTER,tmp_table_2 BY age;
?????? DUMPtmp_table_left_join;
?10.右連接Right Join
????? 1)Mysql
????????SELECT * FROM TMP_TABLE A RIGHT JOIN TMP_TABLE_2 B ON A.AGE=B.AGE;
????? 2)Pig
????????tmp_table_right_join = JOIN tmp_table BY age RIGHT OUTER,tmp_table_2 BY age;
???????? DUMPtmp_table_right_join;
?
11.全連接Full Join
????? 1)Mysql
????????SELECT * FROM TMP_TABLE A? JOIN TMP_TABLE_2 B ON A.AGE=B.AGE
????????????UNION SELECT * FROM TMP_TABLE A LEFT JOIN TMP_TABLE_2 B ON A.AGE=B.AGE
????????????UNION SELECT * FROM TMP_TABLE A RIGHT JOIN TMP_TABLE_2 B ON A.AGE=B.AGE;
????? 2)Pig
????????tmp_table_full_join = JOIN tmp_table BY age FULL OUTER,tmp_table_2 BY age;
???????? DUMPtmp_table_full_join;
?2.同時對多張表交叉查詢
???? 1)Mysql
??????? SELECT *FROM TMP_TABLE,TMP_TABLE_2;
???? 2)Pig
???????tmp_table_cross = CROSS tmp_table,tmp_table_2;
??????? DUMPtmp_table_cross;
?3.分組GROUP BY
??? 1)Mysql
?????? SELECT * FROMTMP_TABLE GROUP BY IS_MALE;
??? 2)Pig
?????? tmp_table_group= GROUP tmp_table BY is_male;
?????? DUMPtmp_table_group;
?14.分組并統(tǒng)計
????? 1)Mysql
??????? SELECTIS_MALE,COUNT(*) FROM TMP_TABLE GROUP BY IS_MALE;
????? 2)Pig
????????tmp_table_group_count = GROUP tmp_table BY is_male;
????????tmp_table_group_count = FOREACH tmp_table_group_count GENERATE group,COUNT($1);
???????? DUMPtmp_table_group_count;
??15.查詢?nèi)ブ?/span>DISTINCT
????? 1)MYSQL
????????SELECT DISTINCT IS_MALE FROM TMP_TABLE;
????? 2)Pig
????????tmp_table_distinct = FOREACH tmp_table GENERATE is_male;
????????tmp_table_distinct = DISTINCT tmp_table_distinct;
????????DUMP? tmp_table_distinct;
總結(jié)
- 上一篇: 《高级无线网络—4G技术》——2.5 超
- 下一篇: mfc 多边形裁剪算法