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语句