# pig基础知识
##基本类型:
```
int 4 byte java.lang.integer
long 8 byte 以 L 结尾
float 4 byte end with 'f'
double 8 byte
chararray similarity to java string
bytearray similarity to java byte[]
```
## 复杂类型
```
Map<chararray,object> ['name'#'lily','age'#18]
由于pig中还有其他复杂结构,map的取值使用 #
Tuple similarity to python ('name'.'lily','age'.18)
Bag {Tuple} 无序的Tuple集合
{('lily',18),('tony',20),('jetty',18)}
```
##Trap
NULL:
* pig中的null代表不确定,什么数据都可以是null,类似sql,不同于java 中null;
* 编写udf 需要主要,如果传入null,java会抛空异常,需要提前filter,或者udf处理
* 任何类型数据和null做预算,最后结果都是null,x==null -> null,判断需要 用 is null
* 一些聚合函数会自动过滤null,例如avg,sum,count
##基本操作
* load 加载数据,加载类型自定义
* store 存储数据
* dump 查看
* illustrate 样本抽取
* explain 查询计划 从下往上看 近数据源型
* group
```
1 与sql有区别,group不会丢失数据,会新开辟一列名为group 的字段,后续是聚合的tuple组成的bag
2 会触发reduce 注意数据倾斜
```
* cogroup 多个数据源的聚合
* foreach :
```
1 比较特殊,除了迭代处理数据,还类似mongodb中的project投影,可以减少字段,编写pig尽量提前减少字段
2 嵌套使用 foreach A { ... generate ...}
3 配合 group 可实现去重计数、分组求和等操作
```
* filter 过滤 可用正则matches
* flatten 拆包,将bag中的包的tuple的字段上推到当前记录中,如果bag有多个tuple,则会生成多条记录
* order by asc/desc 全排序
* distinct 去重,对象是整条记录,不能是字段,会触发reduce
* join
```
内连接 join A by a_id,B by b_id
左连接 join A by (symbol,name) left outer,B by(symbol,name) 连接两个字段
右连接 join A by (symbol,name) outer outer,B by(symbol,name) 连接两个字段
全连接join A by (symbol,name) full outer,B by(symbol,name) 连接两个字段
半连接semi-join,需要自己实现 cogroup + filter + foreach,装包+过滤+拆包
A=load 'input1' as (id,name)
B=load 'input2' as (id,name)
C = cogroup A by id,B by id
D = filter C by not Empty(B)
E = foreach D generate flatten(D)
自连接 数据源加载两次:
A = load 'input1' as ()
B = load 'input1' as ()
join A by id,B by id
```
* limit 注意:没有order 每次数据不保证一样,limit没有读取小部分数据优化策略,依然后读取全部数据
* sample 取样 simle A 0.1 在A中取样10%
* parallel 设置并发reduce数,可以出发reduce的操作:group、order、distinct、join、cogroup、cross(笛卡尔积),可以设置默认值 set default_parallel 10 默认设置10个并发reduce数
##foreach高级应用
##foreach高级应用
```
查找每笔交易对应的不同的股票交易号查询
-- 股票交易,交易号
Input = load 'input1' as (exchange,symbol) ;
A = group Input by exchange;
B = foreach B {
sym = Input.symbol;
-- distinct 只能对记录去重,不能对字段
uniq_sym = distinct sym ;
generate group,COUNT(uniq_sym);
};
注意,foreach嵌套只支持 distinct、filter、limit、order
```
##join连接优化
```
1 大小表连接:stamp邮编schema 连接 全国记录事实表
可以将加载小表到内存分发,避免重复读取schema文件
schema = load 'input1' as(code,lbs)
infact = load 'input2' as(code,name)
j = join infact by code,schema by code using 'replicated'
using'replicated :触发分片-重复join
含义:
分片:对小表(schema)进行分片,加载到内存,不同的分片将会分发到不同的机器上
重复:复制大表重复比对不同分片的小表
只能inner join 和 left join
不能right join,因为 右边是小表schema,如果匹配失败,无法确认其他分片是否能匹配
```
```
2 倾斜数据
skew join 样本抽样,确定分配reduce,
u = load 'input1' as (name,city)
c = load 'input2' as (city,population)
j = join c by city,u by city using 'skewed'
实现:
找出倾斜的key,然后对倾斜的key分配多个reduce;
issue:
会增加抽样时间
增加jvm堆栈的消耗
```
```
3 有序数据
merge join 所有表都是有序数据
j = join A by id,B by id using 'merge'
实现:索引排序
```