MapReduce框架原理之Join
Join
类似SQL的Join,将1张以上的表按照某种关系,将数据进行格式化输出.
1 Reduce Join
Reduce Join工作原理
- Map端的主要工作:为来自不同表或文件的key/value对,
添加标识加以区别不同的数据来源
,然后用join字段作为排序和分组条件(本例是pid)
,其余部分和标识作为value,最后进行输出. - Reduce端的主要工作:在Reduce端以连接字段作为key的分组已经完成,每组数据会调用一个reduce方法,此时我们只需要根据在Map端添加的
标识
将数据分别拿出后,再合并成我们需要的格式即可.
需求:
(1)订单数据表
id | pid | amount |
---|---|---|
1001 | 01 |
1 |
1002 | 02 |
2 |
1003 | 03 |
3 |
1004 | 01 |
4 |
1005 | 02 |
5 |
1006 | 03 |
6 |
(2)商品信息表
pid | pname |
---|---|
01 |
mi |
02 |
iphone |
03 |
blackberry |
(3)最终期望输出结果(按pid升序可以保证,id可能会变成倒序乱,如有特殊要求可以自行调整)
id | pname | amount |
---|---|---|
1001 | mi |
1 |
1004 | mi |
4 |
1002 | iphone |
2 |
1005 | iphone |
5 |
1003 | blackberry |
3 |
1006 | blackberry |
6 |
自定义Bean
package join;
import org.apache.hadoop.io.WritableComparable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class TableBean implements WritableComparable<TableBean> {
private String id;
private String pid;
private int amount;
private String name;
private String tblName;
@Override
public String toString() {
return this.id + "\t" + this.name + "\t" + this.amount;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTblName() {
return tblName;
}
public void setTblName(String tblName) {
this.tblName = tblName;
}
@Override
public void write(DataOutput dataOutput) throws IOException {
dataOutput.writeUTF(this.id);
dataOutput.writeUTF(this.pid);
dataOutput.writeInt(this.amount);
dataOutput.writeUTF(this.name);
dataOutput.writeUTF(this.tblName);
}
@Override
public void readFields(DataInput dataInput) throws IOException {
this.id = dataInput.readUTF();
this.pid = dataInput.readUTF();
this.amount = dataInput.readInt();
this.name = dataInput.readUTF();
this.tblName = dataInput.readUTF();
}
@Override
public int compareTo(TableBean o) {
int result = 0;
if(this.pid.compareTo(o.pid) >