1. 程式人生 > >Hive筆記二

Hive筆記二

HiveQL的增刪改查:

增:

在MYSQL中,我們使用INSERT語句插入資料。但在Hive中,可以使用LOAD DATA語句插入資料。(Insert也可以哦)

同時將資料插入到Hive,最好是使用LOAD DATA來儲存大量記錄。有兩種方法用來載入資料:一種是從本地檔案系統,第二種是從Hadoop檔案系統。

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)

 

刪:

DROP TABLE [IF EXISTS] table_name;

改:

ALTER TABLE name RENAME TO new_name

ALTER TABLE name ADD COLUMNS (col_spec[, col_spec ...])

ALTER TABLE name DROP [COLUMN] column_name

ALTER TABLE name CHANGE column_name new_name new_type

ALTER TABLE name REPLACE COLUMNS (col_spec[, col_spec ...])

查:

SELECT [ALL | DISTINCT] select_expr, select_expr, ...

FROM table_reference

[WHERE where_condition]

[GROUP BY col_list]

[HAVING having_condition]

[CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY col_list]]

[LIMIT number];

連線:(建立在兩個表有相同的列的基礎上,即兩個表的結構相同)

內連線:

內連線進行等值連線,只有當兩個表中指定的屬性相同的前提下才可以進行連線,eg:

SELECT sales.*,things.* FROM sales JOIN things ON (sales.id = things.id);

外連線:外連線可以找到連線表中不能匹配的資料行。

又分為左外連線,右外連線,全外連線;

左外連線:即左側表中有些行無法與所要連線的表中的任何資料行對應,查詢還是會返回這個表中的每一個數據行。

SELECT sales.*,things.* FROM sales LEFT OUTER JOIN things ON (sales.id = thing.id);

右外連線:即右側表中有些行無法與所要連線的表中的任何資料行對應,查詢還是會返回這個表中的每一個數據行。

SELECT sales.*,things.* FROM sales RIGHT OUTER JOIN things ON(sales.id = thing.id);

全外連線:即兩個連線表中的所有行在輸出中都有對應的行。

SELECT sales.*,things.* FROM sales FULL OUTER JOIN things ON(sales.id = thing.id);

檢視:

檢視是一種用SELECT語句定義的虛表,檢視可以用來以一種不同於磁碟實際儲存的形式把資料呈現給使用者,同時,檢視也可以用來限制使用者,使其只能訪問被授權可以看到的表的子集。eg:

CREATE VIEW view_name

AS

SELECT *

FROM XXX

WHERE xxx=xxx AND XXX IN(XXX);

使用者自定義函式:

當我們使用Hive提供的內建函式的時,發現並不能有效的解決我們的問題時,我們可以編寫使用者自定義函式(UDF),UDF必須用Java語言編寫,因為Hive本身就是用Java編寫的,對於其他的程式語言,可以考慮使用SELECT TRANSFORM查詢。Hive有三種UDF(UDF,使用者定義聚集函式,使用者定義表生成函式)區別是:它們所接受的輸入和產生的輸出的資料行的數量不同。

UDF操作用於單個數據行,且產生一個數據行作為輸出。

DDAF接受多個輸入資料行,且產生一個輸出資料行,例如COUNT,MAX這樣的函式

UDTF操作用於單個數據行,且產生多個數據行(即一個表)作為輸出。

UDF:

⑴使用Java編寫UDF函式

package com.dong.hive;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
/**
 * UDF必須滿足兩個條件:
 * 一個UDF必須是org.apache.hadoop.hive.ql.exec.UDF的子類
 * 一個UDF必須至少實現了evaluate()方法
 * 
 * evaluate()方法不是由介面定義的,因為它可接受的引數的個數,資料型別,返回值的資料型別都是不確定的,
 * Hive會檢查UDF,看能否找到和函式呼叫相匹配的evaluate()方法。
 * @author liuD
 *
 */
public class Strip extends UDF{
	private Text result = new Text();
	
	public Text evaluate(Text str) {
		if(str == null) 
			return null;
		result.set(StringUtils.strip(str.toString()));
		return result;
	}
	
	public Text evaluate(Text str,String stripChars) {
		if(str == null)
			return null;
		result.set(StringUtils.strip(str.toString(),stripChars));
		return result;
	}
}

⑵註冊函式

在Hive中要想使用UDF,需要把編譯後的Java類打包成一個JAR檔案,然後再metastore中註冊這個函式並使用CREATE FUNCTION語句為它起名:

CREATE FUNCTION strip As 'com.dong.hive.Strip' USING JAR '/XXX/XXX.jar';

⑶使用UDF函式

SELECT strip('xx') FROM TEST;

⑷刪除函式

DROP FUNCTION strip;

注意:可以建立一個在會話期有效的函式,即扎個函式並沒有在metastore中持久化儲存。

ADD JAR /XXX/XXX.jar CREATE TEMPORARY FUNCTION strip AS 'com.dong.hive.Strip';

UDAF:

⑴使用Java實現UDAF函式

package com.dong.hive;

import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
import org.apache.hadoop.io.IntWritable;
/**
 * 
 * 要求UDAF必須是org.apache.hadoop.hive.ql.exec.UDAF的子類,且包含一個或多個巢狀的,
 * 實現了org.apache.hadoop.hive.ql.UDAFEvaluator的靜態類,
 * 
 * 注意:一個計算函式必須實現下面5個方法:
 * init()方法:負責初始化計算函式並重新設定它的內建狀態
 * iterate()方法:每次對一個新值進行聚集計算時都會呼叫iterate()方法,計算函式根據聚集計算的結果更新其內部
 * 狀態。
 * terminatePartial()方法:hive需要部分聚集結果的時會呼叫terminatePartial()方法,這個方法返回
 * 一個封裝了聚集計算當前狀態的物件。
 * merge()方法:合併一個部分聚集值和另一個部分聚集值時會呼叫merge方法,該方法接受一個物件作為輸入,這個物件
 * 的型別必須和terminatePartial()方法的返回型別一致。
 * terminate()方法:Hive需要最終聚集結果時會呼叫terminate()方法,計算函式需要把狀態作為一個值返回。
 * @author liuD
 */
public class Maximum extends UDAF{
	public static class MaximumIntUDFAEvaluator implements UDAFEvaluator{

		private IntWritable result;
		
		@Override
		public void init() {
			// TODO Auto-generated method stub
			result = null;
		}
		
		public boolean iterate(IntWritable value) {
			if(value == null)
				return true;
			if(result == null) {
				result = new IntWritable(value.get());
			}else {
				result.set(Math.max(result.get(), value.get()));
			}
			return true;
		}
		public IntWritable terminatePartial() {
			return result;
		}
		public boolean merge(IntWritable other) {
			return iterate(other);
		}
		public IntWritable terminate() {
			return result;
		}
	}
}

剩下的步驟和UDF一樣;

我們可以建立一個在會話期間有效的函式,eg:

CREATE TEMPORARY FUNCTION maximum AS 'com.dong.hive.Maximum';

使用函式:

SELECT maximum(temperature) FROM records;

UDTF:

後期更新。

 

內容參考《Hadoop 權威指南》