目录
一、引言
首先先明白在关系型数据库中Join的用法。
Join在MapReduce中的用法也是用于两个文件之间的连接。
使用MR程序解决两张表的join问题,有两种解决方案 à MR程序的join应用
1. reduce端join
在map端将数据封装成Java对象 à 两张表的复合Java对象
在reduce端根据对象值的不同进行join操作
2. map端join
通过缓冲流将小文件存储起来,在map阶段根据对象值的不同进行join操作
二、关系型数据库MySQL中Join的用法
(MySQL中JOIN的用法均整理于https://www.cnblogs.com/fudashi/p/7491039.html)
在关系型数据库中,Join主要用于两张表的连接,就如同英语单词“join”一样,可以分为内连接、外连接、左连接、右连接、自然连接。
笛卡尔积:CROSS JOIN
笛卡尔积是将A表中的数据和B表中的数据组合在一起,假设A表中有n条记录,B表中有m条记录,经过笛卡尔积组合后就会产生n * m条记录。
内连接:INNER JOIN
内连接INNER JOIN是最常用的连接操作(即求两个表的交集),从笛卡尔积的角度来说就是从笛卡尔积中挑出ON子句成立的记录。有INNER JOIN,WHERE(等值连接),STRAIGHT_JOIN,JOIN(省略INNER)四种写法。
左连接:LEFT JOIN
左连接就是求两个表的交集以及左表的其余数据。从笛卡尔积的角度讲,就是先从笛卡尔积中跳出ON字句条件成立的记录,然后加上左表中剩余的记录。
右连接:RIGHT JOIN
与左连接相同,就是求两个表的交集以及右表的其余数据。
外连接:OUTER JOIN
外连接就是求两个集合的并集。从笛卡尔积的角度讲就是从笛卡尔积中挑出ON字句条件成立的记录,然后加上左表中剩余的记录,再加上右表中剩余的记录。MySQL不支持OUTER JOIN,但是可以对左连接和右连接的结果做UNION操作来实现。
三、Reduce Join
1. Reduce Join介绍
2. 案例
2.1 需求:
订单数据表t_order:
id |
pid |
amount |
1001 |
01 |
1 |
1002 |
02 |
2 |
1003 |
03 |
3 |
商品信息表t_product
pid |
pname |
01 |
小米 |
02 |
华为 |
03 |
格力 |
要求将商品信息表中数据根据商品pid合并到订单数据表中。
最终数据形式:
id |
pname |
amount |
1001 |
小米 |
1 |
1004 |
小米 |
4 |
1002 |
华为 |
2 |
1005 |
华为 |
5 |
1003 |
格力 |
3 |
1006 |
格力 |
6 |
如果想要实现这一功能,使用MySQL可以利用Select id, b.pname, a.amount from t_order as a left join t_product as b on a.pid=b.pid 轻松实现。但是如果数据量庞大的话,利用MySQL来实现将会耗费非常久的时间,无法即时完成需求。而使用MapReduce可以解决这一问题。
2.2 实现思路:reduce端表合并(数据倾斜)
通过将关联条件作为map输出的key,将两表满足join条件的数据并携带数据所来源的文件信息,发往同一个reduce task,在reduce中进行数据的串联。
2.3 步骤
第一步:JavaBean对象的编写
先声明一个JavaBean对象---OrderBean,该JavaBean对象是一个复合的JavaBean,其中涵盖了两张表涉及到的所有信息。order表会用到这个bean,product也会用到一个bean。所以为了区分两个表,应该设置一个变量flag,用于定义该表是order表还是product表。同时,为了将这个bean作为一个序列化信息进行中间值传递与输出,还需要将这个bean继承Writable类实现自定义序列化,并且实现其中的序列化和反序列化方法。
第二步: