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 权威指南》