5、多表关联

多表关联和单表关联类似,它也是通过对原始数据进行一定的处理,从其中挖掘出关心的信息。下面进入这个实例。

5.1 实例描述

输入是两个文件,一个代表工厂表,包含工厂名列和地址编号列;另一个代表地址表,包含地址名列和地址编号列。要求从输入数据中找出工厂名地址名对应关系,输出"工厂名——地址名"表。

样例输入如下所示。

1)factory:

factoryname                    addressed

Beijing Red Star                    1

Shenzhen Thunder                3

Guangzhou Honda                2

Beijing Rising                       1

Guangzhou Development Bank      2

Tencent                        3

Back of Beijing                     1

2)address:

addressID    addressname

1            Beijing

2            Guangzhou

3            Shenzhen

4            Xian

样例输出如下所示。

factoryname                        addressname

Back of Beijing                          Beijing

Beijing Red Star                        Beijing

Beijing Rising                          Beijing

Guangzhou Development Bank          Guangzhou

Guangzhou Honda                    Guangzhou

Shenzhen Thunder                    Shenzhen

Tencent                            Shenzhen

5.2 设计思路

多表关联和单表关联相似,都类似于数据库中的自然连接。相比单表关联,多表关联的左右表和连接列更加清楚。所以可以采用和单表关联的相同处理方式,map识别出输入的行属于哪个表之后,对其进行分割,将连接的列值保存在key中,另一列和左右表标识保存在value中,然后输出。reduce拿到连接结果之后,解析value内容,根据标志将左右表内容分开存放,然后求笛卡尔积,最后直接输出。

这个实例的具体分析参考单表关联实例。下面给出代码。

5.3 程序代码

程序代码如下所示:

package com.hebut.mr;

import java.io.IOException;

import java.util.*;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.io.IntWritable;

import org.apache.hadoop.io.Text;

import org.apache.hadoop.mapreduce.Job;

import org.apache.hadoop.mapreduce.Mapper;

import org.apache.hadoop.mapreduce.Reducer;

import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;

import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import org.apache.hadoop.util.GenericOptionsParser;

public class MTjoin {

public static int time = 0;

/*

* 在map中先区分输入行属于左表还是右表,然后对两列值进行分割,

* 保存连接列在key值,剩余列和左右表标志在value中,最后输出

*/

public static class Map extends Mapper<Object, Text, Text, Text> {

// 实现map函数

public void map(Object key, Text value, Context context)

throws IOException, InterruptedException {

String line = value.toString();// 每行文件

String relationtype = new String();// 左右表标识

// 输入文件首行,不处理

if (line.contains("factoryname") == true

|| line.contains("addressed") == true) {

return;

}

// 输入的一行预处理文本

StringTokenizer itr = new StringTokenizer(line);

String mapkey = new String();

String mapvalue = new String();

int i = 0;

while (itr.hasMoreTokens()) {

// 先读取一个单词

String token = itr.nextToken();

// 判断该地址ID就把存到"values[0]"

if (token.charAt(0) >= '0' && token.charAt(0) <= '9') {

mapkey = token;

if (i > 0) {

relationtype = "1";

else {

relationtype = "2";

}

continue;

}

// 存工厂名

mapvalue += token + " ";

i++;

}

// 输出左右表

context.write(new Text(mapkey), new Text(relationtype +"+"+ mapvalue));

}

}

/*

* reduce解析map输出,将value中数据按照左右表分别保存,

  * 然后求出笛卡尔积,并输出。

*/

public static class Reduce extends Reducer<Text, Text, Text, Text> {

// 实现reduce函数

public void reduce(Text key, Iterable<Text> values, Context context)

throws IOException, InterruptedException {

// 输出表头

if (0 == time) {

context.write(new Text("factoryname"), newText("addressname"));

time++;

}

int factorynum = 0;

String[] factory = new String[10];

int addressnum = 0;

String[] address = new String[10];

Iterator ite = values.iterator();

while (ite.hasNext()) {

String record = ite.next().toString();

int len = record.length();

int i = 2;

if (0 == len) {

continue;

}

// 取得左右表标识

char relationtype = record.charAt(0);

// 左表

if ('1' == relationtype) {

factory[factorynum] = record.substring(i);

factorynum++;

}

// 右表

if ('2' == relationtype) {

address[addressnum] = record.substring(i);

addressnum++;

}

}

// 求笛卡尔积

if (0 != factorynum && 0 != addressnum) {

for (int m = 0; m < factorynum; m++) {

for (int n = 0; n < addressnum; n++) {

// 输出结果

context.write(new Text(factory[m]),

new Text(address[n]));

}

}

}

}

}

public static void main(String[] args) throws Exception {

Configuration conf = new Configuration();

// 这句话很关键

conf.set("mapred.job.tracker", "192.168.1.2:9001");

String[] ioArgs = new String[] { "MTjoin_in", "MTjoin_out" };

String[] otherArgs = new GenericOptionsParser(conf, ioArgs).getRemainingArgs();

if (otherArgs.length != 2) {

System.err.println("Usage: Multiple Table Join <in> <out>");

System.exit(2);

}

Job job = new Job(conf, "Multiple Table Join");

job.setJarByClass(MTjoin.class);

// 设置Map和Reduce处理类

job.setMapperClass(Map.class);

job.setReducerClass(Reduce.class);

// 设置输出类型

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(Text.class);

// 设置输入和输出目录

FileInputFormat.addInputPath(job, new Path(otherArgs[0]));

FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));

System.exit(job.waitForCompletion(true) ? 0 : 1);

}

}

5.4 代码结果

1)准备测试数据

通过Eclipse下面的"DFS Locations"在"/user/hadoop"目录下创建输入文件"MTjoin_in"文件夹(备注:"MTjoin_out"不需要创建。)如图5.4-1所示,已经成功创建。

                 

图5.4-1 创建"MTjoin_in"                                                             图5.4.2 上传两个数据表

然后在本地建立两个txt文件,通过Eclipse上传到"/user/hadoop/MTjoin_in"文件夹中,两个txt文件的内容如"实例描述"那两个文件一样。如图5.4-2所示,成功上传之后。

从SecureCRT远处查看"Master.Hadoop"的也能证实我们上传的两个文件。

图5.4.3 两个数据表的内容

2)查看运行结果

这时我们右击Eclipse的"DFS Locations"中"/user/hadoop"文件夹进行刷新,这时会发现多出一个"MTjoin_out"文件夹,且里面有3个文件,然后打开双其"part-r-00000"文件,会在Eclipse中间把内容显示出来。如图5.4-4所示。

图5.4-4 运行结果

转载于:https://www.cnblogs.com/zhanghuijunjava/archive/2013/05/22/3092728.html

一对多表关联(转载虾皮工作室)相关推荐

  1. 后盾网lavarel视频项目---lavarel多表关联一对多操作实例

    后盾网lavarel视频项目---lavarel多表关联一对多操作实例 一.总结 一句话总结: 1.一对多中多那个部分的数据前端通过json弄到服务器 2.所有通过一操作多的时候,都要用上模型中定义的 ...

  2. 7.Mybatis关联表查询(这里主要讲的是一对一和一对多的关联查询)

    视频地址:http://edu.51cto.com/sd/be679 在Mybatis中的管理表查询这里主要介绍的是一对一和一对多的关联查询的resultMap的管理配置查询,当然你也可以用包装类来实 ...

  3. SQL一对多,子表关联查询

    SQL一对多,子表关联查询 两张表:主表A(合作伙伴),从表B(维修方式) 表关系:A:B-----1:N 表A: 只有2条合作伙伴记录 表B: 主从表关联字段:partner_id 目前从表B中有两 ...

  4. 1对多 只取一条 mysql_MySQL 多表关联一对多查询实现取最新一条数据的方法示例...

    本文实例讲述了MySQL 多表关联一对多查询实现取最新一条数据的方法.分享给大家供大家参考,具体如下: MySQL 多表关联一对多查询取最新的一条数据 遇到的问题 多表关联一对多查询取最新的一条数据, ...

  5. 【转载】salesforce 零基础开发入门学习(四)多表关联下的SOQL以及表字段Data type详解...

    salesforce 零基础开发入门学习(四)多表关联下的SOQL以及表字段Data type详解 建立好的数据表在数据库中查看有很多方式,本人目前采用以下两种方式查看数据表. 1.采用schema ...

  6. 实现关联表查询(转载自孤傲苍狼)

    一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...

  7. Hibernate(九)一对多双向关联映射

    上次的博文Hibernate从入门到精通(八)一对多单向关联映射中,我们讲解了一下一对多单向映射的相关 内容,这次我们讲解一下一对多双向映射的相关内容. 一对多双向关联映射 一对多双向关联映 射,即在 ...

  8. hibernate的映射之二(一对多双向关联)

    hibernate的一对多双关联 一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多 hihernate一对多关联映射(双向Dept<----->Emp) 一对多双 ...

  9. MapRedece(单表关联)

    源数据:Child--Parent表 Tom Lucy Tom Jack Jone Lucy Jone Jack Lucy Marry Lucy Ben Jack Alice Jack Jesse T ...

最新文章

  1. 【PHP 每日函数】第 03 周期
  2. 如何给字体添加底色indesign_“美哉汉字”2020字体设计专家工作坊预告+报名
  3. 程序员求职的六大禁忌,你中招了吗?
  4. 2004-4-3+ asp.net编程环境的配置
  5. angularJs为什么在近几年风头一时无二?
  6. 公司有代理 虚拟机安装ubuntu不能上外网
  7. 【C++入门】从C到C++
  8. HanLP1.5.2 -python使用介绍
  9. 前端js如何生成一个对象,并转化为json字符串
  10. 常见面试题学习(5)
  11. CISSP 认证的 12 部优秀 CISSP 书籍和学习指南+学习网站
  12. java se 通用能力-判断推理专项练习(选择题)
  13. 太赞了!分享一个数据科学利器 PyCaret,几行代码搞定从数据处理到模型部署
  14. 题目0063-射击比赛
  15. 【折纸】如何折一个装桌面垃圾的纸盒子
  16. 海外社交媒体常用图片尺寸大全
  17. 汉塞尔曼的奇妙时事通讯:2013年2月4日
  18. 关于F4高级定时器死区时间的计算
  19. P1217 [USACO1.5]回文质数 Prime Palindromes(素数筛法/打表)
  20. Sci-Hub创始人收到苹果的通知:2年前就把她的账户数据给了FBI

热门文章

  1. 三、IDEA更换主题皮肤
  2. 工控机和通用计算机相比的特点,工控机特点
  3. linux切换用户时 su-,Linux切换用户(su)
  4. 【文件上传绕过】——二次渲染漏洞
  5. Codefroces 366 C Dima and Salad(dp)
  6. vue2实现海康威视根据海康插件进行监控实时预览和回放功能,全套代码,开箱即用。
  7. 渡过“去小米化”阵痛期,华米科技能否自立?
  8. 解决“手机能胜场使用校园网 笔记本电脑连接不上校园网或者连接上不可用”的问题
  9. 【带移动搜索功能】织梦dedecms手机WAP插件专业版 织梦自动建手机WAP站 PC+WAP数据同步更新 访问自动跳转
  10. 对面积的曲面积分中dS与dxdy的转换