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