Hive笔记整理

Hive 视图

1、视图的特点:

①不支持物化视图
②只能查询,不能做加载数据操作 load data into
③视图的创建,只是保存一份元数据,查询视图时才执行对应的子查询
④view定义中若包含了ORDER BY/LIMIT语句,当查询视图时也进行ORDER BY/LIMIT语句操作,view当中定义的优先级更高
⑤view支持迭代视图
⑥一旦创建成功,无法修改

2、为什么创建视图?

select a.name,b.age from table1 a join table2 b on(a.id=b.id) => view
如果后期经常执行这个查询语句,每次都写麻烦
可以将长的SQL(数据表)与视图对应映射,每次查询这个视图就是执行了长的SQL语句

3、视图操作

#创建视图
CREATE VIEW  IF NOT EXISTS  view1 AS SELECT * FROM logtbl order by age;
#可以查看已经创建的视图
show tables
#删除视图
drop view view1 

创建视图的时候不会启动MR任务
select * from view1;
但是在查询视图的时候会启动MR任务
视图的创建,只是保存一份元数据,查询视图时才执行对应的子查询

Hive 索引

索引

优化查询性能
若使用select * from table where age = 10;假设这个表的数据非常大,是有10个block组成
name查询的性能会很低
提高性能?
索引1(age > 10) block1(100,200) block2(200,389)
索引2(age = 10) block1(101,220) block2(200,389)
这个索引就类似目录

创建索引库,用于存放索引

create index t2_index on table psnbucket_partition(age) 
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild 
in table t2_index_table;

索引库中只是保存一些元数据,比如 对哪个字段创建索引,对哪个表创建索引等

alter index t2_index on psnbucket_partition rebuild; 

这一步是真正的创建索引信息,并且存储到索引库中,若数据库有新增数据,也可以使用以上语句重建索引

查看索引库:

66 hdfs://zfg/user/hive_remote/warehouse/psnbucket_partition/height=188.0/000000_0 [0,30,60,90,120] 188.0
77 hdfs://zfg/user/hive_remote/warehouse/psnbucket_partition/height=188.0/000000_0 [8,38,68,98,128] 188.0
88 hdfs://zfg/user/hive_remote/warehouse/psnbucket_partition/height=188.0/000000_0 [19,49,79,109,139] 188.0
11 hdfs://zfg/user/hive_remote/warehouse/psnbucket_partition/height=189.0/000000_0 [0,48,96,144,192] 189.0
22 hdfs://zfg/user/hive_remote/warehouse/psnbucket_partition/height=189.0/000000_0 [9,57,105,153,201] 189.0
查询索引:
show index on psnbucket_partition;

删除索引
drop index t2_index on psnbucket_partition;
删除索引的同时 索引库也会被删除

数据读取规则

之前往hive中加载的数据都是比较规整的,字段与字段之间都是分割好的,每一个字段都不是脏数据,并且每一个字段都是有意义的
但是在真实场景中不见得这个尽人意
tomcat运行日志
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] “GET /bg-upper.png HTTP/1.1” 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] “GET /bg-nav.png HTTP/1.1” 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] “GET /asf-logo.png HTTP/1.1” 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] “GET /bg-button.png HTTP/1.1” 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] “GET /bg-middle.png HTTP/1.1” 304 -
192.168.57.4 - - [29/Feb/2016:18:14:36 +0800] “GET / HTTP/1.1” 200 11217

 CREATE TABLE logtbl (
    host STRING,
    identity STRING,
    t_user STRING,
    time STRING,
    request STRING,
    referer STRING,
    agent STRING)
  ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
  WITH SERDEPROPERTIES (
    "input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) \\[(.*)\\] \"(.*)\" (-|[0-9]*) (-|[0-9]*)"
  )
  STORED AS TEXTFILE;

load data local inpath “/root/lo” into table logtbl;
原始脏数据不会变,只是在读的时候,将脏数据清理掉再显示出来。

192.168.57.4 - - 123保存到文件loerr中,然后将文件加载到上面已经创建好的表中
load data local inpath “/root/loerr” into table logtbl; 这一步没问题,因为load就是将数据拷贝到工作目录区中
查询看一下select * from logtbl 读不懂,因为根据正则表达式的模板来读数据,都不懂

总结:

读时检查
不是写时检查

beeline

之前在操作hive的是,直接通过hive命令进入hive cli进行数据分析以及处理,这种方式既不安全有不规范
beeline是一个新兴的cli客户端 类似jdbc/odbc 可以解决一切的问题,并且还能够很好的解耦合
hive client直接连接HDFS、yarn
beeline需要先与thriftserver连接,thriftserver能够进行安全认证、可靠认证、提高客户端的并发

beeline默认链接hiveserver2的时候,不需要用户名 密码,默认方式也是不安全,我们可以设置hiveserver2用户名、密码
设置用户名、密码的步骤:
在hive-site.xml中添加一下信息:

hive.server2.authentication
CUSTOM

    <property>
            <name>hive.jdbc_passwd.auth.zhangsan</name>
            <value>123456789</value>
    </property>
    <property>
            <name>hive.server2.custom.authentication.class</name>
            <value>com.hoe.hive.authoriz.UserPasswdAuth</value>
    </property>
写代码:
	package com.hoe.hive.authoriz;
	import javax.security.sasl.AuthenticationException;
	import org.apache.hadoop.conf.Configuration;
	import org.apache.hadoop.hive.conf.HiveConf;
	import org.apache.hive.service.auth.PasswdAuthenticationProvider;
	import org.slf4j.Logger;
	import org.slf4j.LoggerFactory;

	public class UserPasswdAuth implements PasswdAuthenticationProvider {
		Logger logger = LoggerFactory.getLogger(UserPasswdAuth.class);
		private static final String USER_PASSWD_AUTH_PREFIX = "hive.jdbc_passwd.auth.%s";
		private Configuration conf = null;
		@Override
		public void Authenticate(String userName, String passwd) throws AuthenticationException {
			logger.info("user: " + userName + " try login.");
			String passwdConf = getConf().get(String.format(USER_PASSWD_AUTH_PREFIX, userName));
			if (passwdConf == null) {
				String message = "沒有發現密碼 " + userName;
				logger.info(message);
				throw new AuthenticationException(message);
			}
			if (!passwd.equals(passwdConf)) {
				String message = "用戶名密碼不匹配 " + userName;
				throw new AuthenticationException(message);
			}
		}
		public Configuration getConf() {
			if (conf == null) {
				this.conf = new Configuration(new HiveConf());
			}
			return conf;
		}
		public void setConf(Configuration conf) {
			this.conf = conf;
		}
	}

第一种链接方式:./beeline -u jdbc:hive2://node01:10000/test -n zhangsan -p123456789
第二种链接方式:
./beeline
!connect jdbc:hive2://node01:10000/test
输入用户名
输入密码

JDBC连接操作

因为通过JDBC链接hive 也是链接hiveserver2服务,链接成功才能操作hive
所以JDBC链接的时候也是需要用户名 密码的

package com.hoe.hive.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class ConnectHive {

	public static String driverName = "org.apache.hive.jdbc.HiveDriver";

	public static void main(String[] args) {

		try {
			Class.forName(driverName);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		String url = "jdbc:hive2://node01:10000";
		String userName = "zhangsan";
		String passwd = "123456789";
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(url, userName, passwd);
			Statement statement = conn.createStatement();
			String sql = "select * from test.logtbl limit 10";
			ResultSet resultSet = statement.executeQuery(sql);
			while (resultSet.next()) {
				System.out.println(resultSet.getString(1) + "-" + resultSet.getString(2));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}

Hive内置函数

使用hive实现wordcount

创建数据表

create table docs(line string);

创建结果表

create table wc(word string, totalword int);

加载数据

load data local inpath ‘/tmp/wc’ into table docs;

统计wordcount并且将数据插入到结果表中

from (select explode(split(line, ' ')) as word from docs) w 
insert into table wc 
 select word, count(1) as totalword 
 group by word 
 order by word;

查询结果

select * from wc;

自定义UDF

add jar /opt/software/hive/hive-1.2.1/lib/FormatTimeUDF.jar;
CREATE TEMPORARY FUNCTION convertTime AS 'com.hoe.hive.userdefinedfunction.FormatTimeUDF';
select convertTime(time) from logtbl;
DROP TEMPORARY FUNCTION convertTime;

自定义UDAF

add jar /opt/software/hive/hive-1.2.1/lib/ReduceTimeByResponseNumUDAF.jar;
CREATE TEMPORARY FUNCTION rrd AS ‘com.hoe.hive.userdefinedfunction.ReduceTimeByResponseNumUDAF’;
select referer,rrd(host) from logtbl group by referer;
DROP TEMPORARY FUNCTION rrd;

自定义UDTF

add jar /opt/software/hive/hive-1.2.1/lib/UserGenericUDTF.jar;
CREATE TEMPORARY FUNCTION exp AS ‘com.hoe.hive.userdefinedfunction.UserGenericUDTF’;
select exp(line) from udtfc;

永久函数

将相应的jar包上传到HDFS上
create function formatTime AS ‘com.hoe.hive.userdefinedfunction.FormatTimeUDF’ using jar ‘hdfs://zfg/test/FormatTimeUDF.jar’;
create function exp AS ‘com.hoe.hive.userdefinedfunction.UserGenericUDTF’ using jar ‘hdfs://zfg//test/UserGenericUDTF.jar’;
create function rrd AS ‘com.hoe.hive.userdefinedfunction.ReduceTimeByResponseNumUDAF’ using jar ‘hdfs://zfg//test/ReduceTimeByResponseNumUDAF.jar’;

Hive脚本运行方式:

不在hive中运行
hive -e “sql语句”–>显示结果后退出
hive -e > “目录” 追加结果到目录中
hive -S -e “” :进入hive的静默模式,只显示查询结果,不显示执行过程
hive -f file:执行HQL(符合98-03标准)脚本
hive -i “HQL脚本文件目录”:执行Hive交互Shell时候先执行脚本中的HQL语句

猜你喜欢

转载自blog.csdn.net/qq_40262690/article/details/83997979