一对多表关联(转载虾皮工作室)
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
一对多表关联(转载虾皮工作室)相关推荐
- 后盾网lavarel视频项目---lavarel多表关联一对多操作实例
后盾网lavarel视频项目---lavarel多表关联一对多操作实例 一.总结 一句话总结: 1.一对多中多那个部分的数据前端通过json弄到服务器 2.所有通过一操作多的时候,都要用上模型中定义的 ...
- 7.Mybatis关联表查询(这里主要讲的是一对一和一对多的关联查询)
视频地址:http://edu.51cto.com/sd/be679 在Mybatis中的管理表查询这里主要介绍的是一对一和一对多的关联查询的resultMap的管理配置查询,当然你也可以用包装类来实 ...
- SQL一对多,子表关联查询
SQL一对多,子表关联查询 两张表:主表A(合作伙伴),从表B(维修方式) 表关系:A:B-----1:N 表A: 只有2条合作伙伴记录 表B: 主从表关联字段:partner_id 目前从表B中有两 ...
- 1对多 只取一条 mysql_MySQL 多表关联一对多查询实现取最新一条数据的方法示例...
本文实例讲述了MySQL 多表关联一对多查询实现取最新一条数据的方法.分享给大家供大家参考,具体如下: MySQL 多表关联一对多查询取最新的一条数据 遇到的问题 多表关联一对多查询取最新的一条数据, ...
- 【转载】salesforce 零基础开发入门学习(四)多表关联下的SOQL以及表字段Data type详解...
salesforce 零基础开发入门学习(四)多表关联下的SOQL以及表字段Data type详解 建立好的数据表在数据库中查看有很多方式,本人目前采用以下两种方式查看数据表. 1.采用schema ...
- 实现关联表查询(转载自孤傲苍狼)
一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...
- Hibernate(九)一对多双向关联映射
上次的博文Hibernate从入门到精通(八)一对多单向关联映射中,我们讲解了一下一对多单向映射的相关 内容,这次我们讲解一下一对多双向映射的相关内容. 一对多双向关联映射 一对多双向关联映 射,即在 ...
- hibernate的映射之二(一对多双向关联)
hibernate的一对多双关联 一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多 hihernate一对多关联映射(双向Dept<----->Emp) 一对多双 ...
- MapRedece(单表关联)
源数据:Child--Parent表 Tom Lucy Tom Jack Jone Lucy Jone Jack Lucy Marry Lucy Ben Jack Alice Jack Jesse T ...
最新文章
- 【PHP 每日函数】第 03 周期
- 如何给字体添加底色indesign_“美哉汉字”2020字体设计专家工作坊预告+报名
- 程序员求职的六大禁忌,你中招了吗?
- 2004-4-3+ asp.net编程环境的配置
- angularJs为什么在近几年风头一时无二?
- 公司有代理 虚拟机安装ubuntu不能上外网
- 【C++入门】从C到C++
- HanLP1.5.2 -python使用介绍
- 前端js如何生成一个对象,并转化为json字符串
- 常见面试题学习(5)
- CISSP 认证的 12 部优秀 CISSP 书籍和学习指南+学习网站
- java se 通用能力-判断推理专项练习(选择题)
- 太赞了!分享一个数据科学利器 PyCaret,几行代码搞定从数据处理到模型部署
- 题目0063-射击比赛
- 【折纸】如何折一个装桌面垃圾的纸盒子
- 海外社交媒体常用图片尺寸大全
- 汉塞尔曼的奇妙时事通讯:2013年2月4日
- 关于F4高级定时器死区时间的计算
- P1217 [USACO1.5]回文质数 Prime Palindromes(素数筛法/打表)
- Sci-Hub创始人收到苹果的通知:2年前就把她的账户数据给了FBI
热门文章
- 三、IDEA更换主题皮肤
- 工控机和通用计算机相比的特点,工控机特点
- linux切换用户时 su-,Linux切换用户(su)
- 【文件上传绕过】——二次渲染漏洞
- Codefroces 366 C Dima and Salad(dp)
- vue2实现海康威视根据海康插件进行监控实时预览和回放功能,全套代码,开箱即用。
- 渡过“去小米化”阵痛期,华米科技能否自立?
- 解决“手机能胜场使用校园网 笔记本电脑连接不上校园网或者连接上不可用”的问题
- 【带移动搜索功能】织梦dedecms手机WAP插件专业版 织梦自动建手机WAP站 PC+WAP数据同步更新 访问自动跳转
- 对面积的曲面积分中dS与dxdy的转换