1. 程式人生 > >我的hadoop初學程式----------------多表連線-----------資料庫多表自然連線------MTJoin

我的hadoop初學程式----------------多表連線-----------資料庫多表自然連線------MTJoin

輸入檔案1:

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:

addressID    addressname
1 Beijing
2 Guangzhou
3 Shenzhen
4 Xian

要想得到的輸出檔案:

factoryname	addressname
Beijing Red Star                	Beijing 
Beijing Rising                       	Beijing 
Back of Beijing                     	Beijing 
Guangzhou Honda                      	Guangzhou 
Guangzhou Development Bank             	Guangzhou 
Shenzhen Thunder                     	Shenzhen 
Tencent                         	Shenzhen 


自己編寫的執行正確的map/reduce原始碼:

package bin;

import java.io.IOException;
import java.util.Iterator;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
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 class MTJoinMap extends Mapper<Object, Text, Text, Text>{
		//map做的事是將不同檔案中的資料進行處理分發;繼承了mapper之後就要實現其中的map方法
		public void map(Object key,Text value,Context context) {
			//每次執行map函式,就會讀取檔案中的一行資料給value,要對value進行處理;
			String line=new String(value.toString());
			String MapKey=new String();
			String MapValue=new String();
			
			if (line.contains("factoryname")||line.contains("addressed")||line.contains("addressID")||line.contains("addressname")) {
				return;
			}
			int len=line.length();
			String flag=new String();//記錄屬於左表還是屬於右表;
			//每個map任務按行讀取檔案,將讀取的一行資料交給map函式執行處理,即,每一行資料呼叫一次map函式,
			//所以這裡的一個tokenizer的容器,包含的資料,在這裡只有兩個,當讀取下一行資料時,就會再次呼叫一次MTJoinMap的map函式
			//------------------------------由此,這裡的i的意義就很明顯了。
			//當每一行資料讀進來初始時,i的值均為0,所以當檔案為第一個檔案,即第二位為ID時,flag="1",當檔案為第一個檔案時,即第一位為ID,則,i=0,--> flag="2"
			String[] record=line.split(" ");
			if (len==0) {
				return;
			}else {
				if (line.charAt(0) > '0' && line.charAt(0) < '9') {
					flag="2";
					MapKey=String.valueOf(line.charAt(0));
					for (int i = 1; i < record.length; i++) {
						MapValue =MapValue.concat(record[i]).concat(" ");
					}
					
				}else if (line.charAt(len-1) > '0' && line.charAt(len-1) < '9') {
					flag="1";
					MapKey=String.valueOf(line.charAt(len-1));
					for (int i = 0; i < record.length-1; i++) {
						if (record[i].equals(" ")) {
							continue;
						}
						MapValue =MapValue.concat(record[i]).concat(" ");
					}
				}
				try {
					context.write(new Text(MapKey), new Text(flag+"+"+MapValue));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
		
	}
	public static int time=0;
	
	public static class MTJoinReduce extends Reducer<Text, Text, Text, Text>{
		public void reduce(Text key,Iterable<Text> values,Context context) {
			
			if (time==0) {
				try {
					context.write(new Text("factoryname"), new Text("addressname"));
				} catch (IOException | InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
                time++; 
			}//輸出表頭資訊factory name address name
			
			String[]  factoryname=new String[10];
			int factoryNum=0;
			String addressname=new String();
			
			Iterator<Text> iterator=values.iterator();
			while (iterator.hasNext()) {
				String record= iterator.next().toString();
				
				int len=record.length();//以下這三句不加會報錯: Exception closing file /user/xinxin/output/MutiTableJoin_out
				if (len==0) {//一定要判定迭代器裡面的字串為空的情況
					continue;
				}
				char flag=record.charAt(0);
				
				if (flag=='1' && record.substring(2).length()!=0) {
					
					factoryname[factoryNum]=record.substring(2);
					factoryNum++;
				}else if (flag=='2' && record.substring(2).length()!=0) 
					addressname = record.substring(2);
			}
			if (factoryNum!=0 && addressname.length()!=0) {
				for (int i = 0; i < factoryNum; i++) {
					try {
						context.write(new Text(factoryname[i]), new Text(addressname));
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	
	public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
		Configuration configuration=new Configuration();
		String[] otherArgs = new GenericOptionsParser(configuration,args).getRemainingArgs();
		 if (otherArgs.length !=2) {
			System.err.println("Usage: MTJoin <in> <out>");
			System.exit(2);
		}
		 Job job =new Job(configuration, "tracert MTJoin");
		 job.setJarByClass(MTJoin.class);
		 
		 job.setMapperClass(MTJoinMap.class);
		 job.setReducerClass(MTJoinReduce.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);
	}
}

作者原創,如果轉載請註明出處,謝謝

---------------------------------------------------------欣

相關推薦

hadoop初學程式----------------連線-----------資料庫自然連線------MTJoin

輸入檔案1: factoryname   addressed Beijing Red Star 1 Shenzhen Thunder 3 Guangzhou Honda 2 Beijing Rising 1 Guangzhou Development Bank 2 Ten

關於java通過proxool連線資料庫資料來源的問題

公司一直是處理大資料這個方面,對資料庫操作頻繁在所難免,關於資料庫連線方式換了很多,各有優缺點,具體就不在這解釋了。 之前一直在用C3P0建立資料來源,但C3P0佔用資源不能及時的釋放,導致資料庫連線數經常丟擲警告資訊(被鎖死),雖然不影響執行,但這樣下去也不是辦法,所以決

連線資料庫(java驅動連線連線連線

使用java驅動連線資料庫:        String url ="jdbc:mysql://localhost:3306/zhongruan";        String usernam

使用連線池的方式連線資料庫:使用DBUtil連線MYSQL資料庫

==================== DBUtil.java: ==================== package blog.util; import java.sql.Connection; import java.sql.PreparedStatement

連線、右連線和內連結(自然連線)

前兩天面試時被問到資料庫左連線,原題是:A、B表中各有4條資料,A表左連線B表時會顯示多少條資料?當時腦殘的說了句:16條!唉~悲催的。。。一下子體現了自己在資料庫方面的弱項,回來之後補習了一下,在此記錄一下個人學習之後的總結: 1、左連線 左連線基本格式為A left join B

8、mysql資料庫查詢(資料並集、內連線、左連結、右連結、全連線

目錄 1 內連線 場景:A和B資料 的交集 2 左連結 場景1:得到 “AB交集後和A“ 的並集  (得到A的所有資料+滿足某一條件的B的資料) 場景2:得到A減去AB的交集  (A中所有資料減去同時滿足B某一條件的資料) 3 右連結 場景1:得到“A

解決執行緒程式使用JDBC連線資料庫的異常

多執行緒就帶來了高併發,短時間內大量的請求發向資料庫,在執行過程中出現了以下錯誤: ** BEGIN NESTED EXCEPTION ** com.mysql.jdbc.CommunicationsException MESSAGE: Communi

Hibernate 連線訪問個數據庫(含訪問不同資料庫的相同)

利用訪問不同資料庫中的不同表或不同資料庫中的相同表。 本人在開發過程中的解決方案,希望大家交流。一般用myEclipse工具會自動生成Hibernate的相關檔案,大致有下面幾類: (1)資料庫配置檔

JDBC(資料庫的驅動、連線、java程式操作資料庫、事務、隔離級別、連線池等)

java操作資料庫的思想:連上資料庫,傳送sql語句。在連上資料庫之前,要先用程式啟動資料庫,因此,可以通過反射載入類驅動(com.jdbc.mysql.Driver)。通過驅動管理類的靜態方法傳遞資料庫的url來獲取一個連線物件(connection)。有三個過載的方法,第一個user和p

JDBC上關於資料庫操作一對關係和關係的實現方法--轉

  原文地址---- https://www.cnblogs.com/pangguoming/p/7028322.html 黑馬程式設計師 我們知道,在設計一個Java bean的時候,要把這些BEAN 的資料存放在資料庫中的表結構,然而這些資料庫中的表直接又有些特殊

SQL與eclipse的連線,從資料庫讀取資料,將二維陣列資料匯入

示例: import java.util.List; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; impor

利用JDBC連線實現跨伺服器跨資料庫資料傳輸

  如題  我現在有兩個伺服器 A和B 我現在要把A伺服器上的某一個庫裡面的所有的表及結構及資料 匯入另外一個伺服器上,實現原理利用原始JDBC 完成 程式碼類:  回家再擼 目前在公司 。。 下班    哈哈 晚上吃了點飯 就回來

pymysql連線資料庫,讀取內容

python中有MySQLdb、pymysql等資料庫模組,本文用pymysql模組連線mysql資料庫,並且讀取資料庫表 看過其他博文的介紹,把程式和資料庫比作兩個目的地,將遊標比喻成運輸貨車 很是形象生動! 我用的是Anaconda的編輯器spyder,首先要先下載pymysql模組到本地才能匯

Day055--MySQL--外來鍵的變種,的關係,單查詢,查詢, 內連線,左右連線,全外連線

表和表的關係 ---- 外來鍵的變種 * 一對多或多對一 多對多 一對一 如何找出兩張表之間的關係 分析步驟: #1、先站在左表的角度去找 是否左表的多條記錄可以對應右表的一條記錄,如果是,則證明左表的一個欄位foreign key 右表一個欄位(通常是id) #2、再站在右表的角度去找 是否右表

【FastCube.Net教程】如何將資料庫連線維資料集

通常,OLAP多維資料集中的資料是從資料庫載入的。要使用資料填充多維資料集,需要建立資料來源,多維資料集可以接收以下資料: Database(資料庫)—建立與資料庫的連線; Stream(流)—可以通過網路作為流接收,從檔案開啟或從資料庫下載的多維資料集; Application code

資料庫關聯對對關係

資料庫多表關聯對多對關係 本文章解決資料庫設計多表關聯配置問題,多對多關係! 設計思路: 應用場景: 1,區域表(欄位:id(城市id)、name(城市名字)) 表名:pms_region 2,中間表(欄位:shipping_area_id、re

如何在 Laravel 中連線個 MySQL 資料庫

  第一步、定義資料庫連結 config/database.php <?php return [ 'default' => 'mysql', 'connections' => [ # 主要資料庫連線 'mysql' => [ 'driver' =&g

JavaFX程式初次執行建立資料庫並執行建SQL

  在我的第一個JavaFX程式完成安裝的時候才突然發現,不能要用這個軟體還要手動執行Sql來建表吧?  於是我的想法是在Main程式中執行時檢測資料庫連線狀況,如果沒有檢測到資料庫或者連線異常,那麼出現錯誤提示,如果資料庫連線沒有問題那麼自動建立資料庫並執行建表Sql進行初始化。 pac

python3 django框架開發(二) 連線資料庫,建

轉載請註明:https://blog.csdn.net/weixin_40490238/article/details/84573309 安裝pymysql包,點選settings 查詢pymysql,點選install package 開啟settings.p

【java小程式實戰】小程式短視訊專案之資料庫

 最近自己在練習一個java小程式短視訊的專案,希望每天通過文章的形式把開發內容和學習到的東西記錄下來。  一個專案的開始就是資料庫建表,首先我們要有一個使用者表,記錄使用者的一些資訊   使用者表-user 欄位