1. Load的使用

//在1.x版本中定义long数据类型会报错(用bigint代替)
create table t_load_stu(name string,age bigint)
row format
delimited fields terminated by ',';

1.1本地在本地导入数据,本地数据不会删除(相当于复制)

//overwrite覆盖表中所有的数据
load data local inpath 文件路径 [overwrite] into table 表名
eg:load data local inpath '/root/apps/hive-data/local_load_stu.dat'
into table t_load_stu;

1.2在hadoop中导入数据,hadoop上的数据被删除(相当于剪切)

load data inpath hadoop上文件目录 into table tab_name
eg:load data inpath '/hivedata/load_stu.dat' into table t_load_stu;
load data inpath '/hivedata/load_stu.dat' overwrite into table t_load_stu;

2.Insert的使用

 (1)创建源数据库
create external table org_stu(phone string,real_name string,age int,
gender int,country string,ip string,creat_time date,creator string)
row format
delimited fields terminated by ','
location '/hivedata';
//修改表中某个字段的类型
alter table org_stu change gender gender string;
//加入本地数据
load data local inpath '/root/apps/hive-data/org_stu.dat' into table org_stu;
(2)为查询出来的数据插入创建表
create table t_copy_stu1(phone string,real_name string,age int)
row format
delimited fields terminated by ',';
(3)创建分区表
create table t_copy_partition_stu(phone string,real_name string,ip string)
partitioned by(creat_time string)
row format
delimited fields terminated by ',';
(4)多重插入准备两张表
create table t_mult_stu_1(phone string,real_name string)
row format
delimited fields terminated by ',';
create table t_mult_stu_2(phone string,gender string,age int)
row format
delimited fields terminated by ',';

2.1将查询出来的结果插入到一个表中

 语法:insert [overwrite]/into table  表名
select 字段 from 表名 where 条件
eg:insert overwrite table t_copy_stu1 select phone,real_name,age from org_stu;

2.2将查询出来的结果作为插入到表中的某个分区中(自动分区模式)

设置自动分区模式:set hive.exec.dynamic.partition.mode=true;
语法:insert overwrite table 表名 partition (分区字段名)
select 字段 from 表名 where 条件
eg:insert overwrite table t_copy_partition_stu partition(creat_time)
select phone,real_name,ip,substring(creat_time,0,10) as creat_time from org_stu;

2.3多重插入

语法:from 表名
insert into table 表名 select 字段名称 where 查询条件
...
eg:from org_stu
insert into table t_mult_stu_1 select phone,real_name
insert into table t_mult_stu_2 select phone,gender,age;

3Select

 表:
create table t_stu_limit_20(sno int,name string,age int,sdp string)
row format
delimited fields terminated by ',';
注:1、set hive.exec.reducers.bytes.per.reducer=<number>,设置每个reducer最大处理的数据大小(单位:字节)来计算出需要多少个reducer去处理,默认大小是:256000000
2、set hive.exec.reducers.max=<number>,设置reducer的最大值,如果上面设置的算出来的reducer的个数超过max的值,以max的值为准.如果上面的计算出reudcer小于max,以小的为准。(默认值是:1009)
3、set mapreduce.job.reduces=<number>固定的设置reducer的个数

3.1 distribute by(字段)根据指定的字段将数据分到不同的reducer,且分发算法是hash散列算法

  注:跟reducer的个数有关,不具有排序
eg:select * from t_stu_limit_20 distribute by sno;

3.2 sort by(字段) 不是全局排序,其在数据进入reducer前完成排序。

  注:如果用sort by 进行排序并且设置mapred.reduce.tasks>1,则sort by 只能保证每个reducer的输出有序,不保证全局有序
eg:select * from t_stu_limit_20 distribute by sno sort by age;

3.3 order by(字段) 会对输入做全局排序

  注:只有一个reducer,缺点是当输入规模较大时需要较长的计算时间
(Number of reduce tasks determined at compile time: 1)
eg:select * from t_stu_limit_20 order by age;

3.4 cluster by(字段) 除了具有distribute by 功能外还可以对该字段进行排序

  注:如果分桶和sort是同一个字段,此时cluster by =distribute by +sort by
eg:insert overwrite local directory '/root/test' select * from t_stu_limit_20 cluster by sno;

分桶的作用:最大的作用是用来提高join操作的效率

补充:如何才能在yarn的管理控制台上查看已经完成的job信息?

需要在hadoop集群上启动jobhistory服务器,执行的命令是:mr-jobhistory-daemon.sh start
historyserver

4 join

注:

1)目前hive只支持等值得join,不支持非等值的连接,因为非等值join很难转化为map/reducer任务

2)可以join多于2个表,执行流程分析

 情况一:如果join多个表时,join key 是同一个,则join会被转化为单个map/reduce任务
eg:select a.val,b.val,c.val from a join b on(a.key=b.key1) join c
on (c.key=b.key1)
情况二:如果join key非同一个,则join会被转化为多个map/reduce的任务
eg:select a.val,b.val,c.val from a join b on(a.key=b.key1) join c
on(c.key=b.key2)
分析:join被转化为2个map/reduce任务。因为b.key1用于第一次join条件,而b.key2用于第二次join.

3)join时,每次map/reduce的任务逻辑

  说明:reducer会缓存join序列中除了最后一个表所有表的记录,再通过最后一个表将结果序列化到文件系统中。
优点:这一实现有助于在reduce端减少内存的使用量。
注:在实践中应该把最大的那个表放在最后,否则会因为缓存浪费大量的缓存。
eg:1)select a.val,b.val,c.val from a join b on(a.key=b.key1) join c
on (c.key=b.key1)
说明:所有的表都使用同一个join key(使用一次map/reduce任务计算)。reduce端会缓存a表和b表的记录,然后每次取得一个c表记录就计算一次join结果。
2)select a.val,b.val,c.val from a join b on(a.key=b.key1) join c
on(c.key=b.key2)
说明:join key不同,这里用了2次map/reduce任务。第一次缓存a表用b表序列化,第二次缓存第一次map/reduce任务的结果,然后用c表序列化。

4)LEFT、RIGHT、FULL 、OUTER关键字用于处理join中空记录的情况

  说明:和数据库处理的差不多

5)join发生在where字句之前

  实际场景问题:select a.val,b.val from a left outer join(a.key=b.key) where a.ds='2016-12-30' and b.ds='2016-12-30'
问题描述:如果b找不到对应的a表的记录,b表所有列都会列出null,包括ds列。也就是说join会过滤b表中不能找到匹配a表join key的所有记录,导致LEFT OUTER与where子句无关。
解决方案:在left out时使用条件
select a.val,b.val from a left outer join on(a.key=b.key and b.ds='2016-12-29' and a.ds='2016-12-29')
说明:这一查询的结果是预先在join阶段过滤的,所以不会存在上述的问题。这一逻辑可以用于right 和full类型的join中。

6)join是不能交换位置的

 说明:无论是left还是right都是通过左连接的。
eg:select a.val1,a.val2,b.val,c.val from a join b on(a.key=b.key) left outer join c on(a.key=b.key)
分析:先join a表到b表的记录,丢弃掉所有join key中不匹配的记录,然后用这中间结果和c表做join.也就是说,就是当一个key在a表和c表都存在,但在b表不存在的时候,整个记录在第一次join,即a join b的时候被丢弃掉了(包括a.val1,a.val2和a.key),然后我们在跟c表join的时候,如果c.key与a.key或b.key相等,就会得到这样的结果:null,null,null,c.val

5hive参数配置

5.1hive的命令行

  语法结构:
hive [-hiveconf x=y]*[<-i filename>]*[<-f filename>|-e query-string][-s]
说明:
1、-i从文件中初始化hql;
2、-e从命令行执行指定的hql
3、-f执行hql脚本
4、-v输出执行的hql语句到控制台
eg:命令:hive -e 'use db2;select * from t_load_stu';
结果:Time taken: 1.02 seconds
OK
zs 12
ls 15
wu 16

5.2参数配置方式

1)配置文件(全局有效)
说明:用户自定义配置文件:hive-site.xml
默认配置文件:hive-default.xml
注: 1>用户自定义配置文会覆盖默认配置;
2>hive会读取hadoop的配置,因为hive作为hadoop的客户端启动的,hive配置会覆盖hadoop的配置
2)命令行参数(对hive启动实例有效)
说明:-hiveconf param=value
eg:-hiveconf hive.root.logger=info,console
3)参数声明(对hive的连接session有效)
说明:可以在hql中使用set关键字来设定参数
eg:1>set hive.exec.reducers.bytes.per.reducer=>每个reduce task的平均负载数据量,hive会估算我们的总数据量,然后用总数据量除以上述参数值,就能得到需要运行的reduce task的数量
2>set hive.exec.reducers.max=>设置reduce task的上限
3>set mapreduce.job.reduces=>指定固定的reduce task的数量
注:这个参数在必要时<业务逻辑决定只能用一个reduce task>会忽略的(例如order by)

6hive函数

创建测试需要的表,方便函数的测试
1、create table dual(id string);
2、load一个文件(一行,一个空格)到dual表中

6.1自定义hive的函数(基于java开发语言)

 步骤:第一步:先开发一个java类,继承UDF,并重载evaluate方法;
第二步:打成jar包上传到服务器;
第三步:将jar包添加到hive的classpath(命令:add jar jar包的全路径);
第四步:创建临时函数与开发好的java class关联(命令:create temporary function 方法名称 as '定义方法类名的全路径');
eg:
1)创建一个java类,集成UDF
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.ql.exec.UDF;
public class MyHiveFunctionUdf extends UDF {
// 重载方法
public String evaluate(String inStr) {
if (StringUtils.isEmpty(inStr)) {
return inStr;
}
return inStr.toLowerCase();
} public int evaluate(Integer... sumParams) {
if (sumParams == null || sumParams.length == 0)
return 0;
int totalValue = 0;
for (Integer sumParam : sumParams) {
if (sumParam != null) {
totalValue += sumParam;
}
}
return totalValue;
} public String evaluate(String... inStrs) {
StringBuffer sb = new StringBuffer();
if (inStrs == null || inStrs.length == 0) {
return "";
}
for (String inStr : inStrs) {
sb.append(inStr);
}
return sb.toString();
}
}
2)打成jar添加到hive的classpath中去
命令:hive> add jar /root/hive-udf.jar;
结果:Added [/root/hive-udf.jar] to class path(加载本地的classpath)
Added resources: [/root/hive-udf.jar](加载到distribute cache中分发到各个map/reduce中)
3)创建临时函数myfuns与com.hive.udf.MyHiveFunctionUdf类映射
命令:create temporary function myfuns as 'com.hive.udf.MyHiveFunctionUdf';
结果:OK
Time taken: 1.194 seconds
4)在hql中使用函数
命令:select myfuns('1','2','3') from dual;
结果:123
命令:select myfuns(1,2) from dual;
结果:3

6.2Transform实现hive自定义的函数

说明:hive的transform关键字提供了在sql中调用自写脚本的功能
eg:
1、创建容纳json数据的表
create table t_json(json_line string)
row format
delimited fields terminated by '\001';
2、使用get_json_object对json表中的json字符串进行解析并保存到新的表中
create table t_rating
as select get_json_object(json_line,'$.movie') as movieid,
get_json_object(json_line,'$.rate') as rate,
get_json_object(json_line,'$.timeStamp') as timestring,
get_json_object(json_line,'$.uid') as userid
from t_json
3、通过transform方式创建通过时间戳获取weekday
python的脚本:
#!/bin/python
import sys
import datetime
for line in sys.stdin:
line = line.strip()
movieid, rating, unixtime,userid = line.split('\t')
weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()
print '\t'.join([movieid, rating, str(weekday),userid])
创建一张记录表:
CREATE TABLE u_data_new (
movieid INT,
rating INT,
weekday INT,
userid INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t';
命令:add file /root/apps/hive-data/weekday-mapper.py(向每个map/reduce发送该脚本)
执行:
INSERT OVERWRITE TABLE u_data_new
SELECT
TRANSFORM (movieid , rate, timestring,userid)
USING 'python weekday-mapper.py'---使用脚本函数
AS (movieid, rating, weekday,userid)
FROM t_rating;
校验是否成功:
select distinct(weekday) from u_data_new limit 10;

7hvie特殊分割符处理

hive读取数据的机制:1、首选用InputFormat<默认是:org.apache.hadoop.mapred.TextInputFormat>的具体实现类读入文件数据,返回一条一条的记录(可以是行或自定义逻辑中的行)
2、然后用SerDe<默认是:org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe>的一个具体实现类,对上面返回一条一条的记录进行字段切割

7.1通过自定义InputFormat解决特殊分隔符的问题

eg:
1、原始数据格式:zs||24
ls||27
2、重写InputFormat
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.FileSplit;
import org.apache.hadoop.mapred.InputSplit;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.LineRecordReader;
import org.apache.hadoop.mapred.RecordReader;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.TextInputFormat;
import com.google.common.base.Charsets;
public class TextInputFormatWrapper extends TextInputFormat {
@Override
public RecordReader<LongWritable, Text> getRecordReader(InputSplit genericSplit, JobConf job, Reporter reporter) throws IOException {
reporter.setStatus(genericSplit.toString());
String delimiter = job.get("textinputformat.record.delimiter");
byte[] recordDelimiterBytes = null;
if (null != delimiter) {
recordDelimiterBytes = delimiter.getBytes(Charsets.UTF_8);
}
LineRecordReader lineRecordReader = new LineRecordReader(job, (FileSplit) genericSplit, recordDelimiterBytes);
return new LineRecordReaderWrapper(lineRecordReader);
}
public static class LineRecordReaderWrapper implements RecordReader<LongWritable, Text> {
private LineRecordReader lineRecordReader;
public LineRecordReaderWrapper(LineRecordReader lineRecordReader) {
super();
this.lineRecordReader = lineRecordReader;
}
@Override
public void close() throws IOException {
lineRecordReader.close();
}
@Override
public LongWritable createKey() {
return lineRecordReader.createKey();
}
@Override
public Text createValue() {
return lineRecordReader.createValue();
}
@Override
public long getPos() throws IOException {
return lineRecordReader.getPos();
}
@Override
public float getProgress() throws IOException {
return lineRecordReader.getProgress();
}
@Override
public boolean next(LongWritable key, Text value) throws IOException {
boolean hasNext = lineRecordReader.next(key, value);
if (hasNext && value != null) {
String replaceResult = value.toString().replaceAll("\\|\\|", "\\|");
value.set(replaceResult);
}
return hasNext;
}
}
}
3、创建表使用该InputFormat
create table t_bi(name string,age int)
row format delimited fields terminated by '|'
stored as inputformat 'com.hadoop.extend.TextInputFormatWrapper'
outputformat 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat';
4、加载数据
load data local inpath '/root/apps/hive-data/bi.dat' into table t_bi;
5、测试结果是
select * from t_bi;
zs 24
ls 27

7.2使用RegexSerDe通过正则表达式来抽取字段

eg:
1、 创建表,使用serde为org.apache.hadoop.hive.serde2.RegexSerDe
create table t_bi_reg(name string,age int)
row format
serde 'org.apache.hadoop.hive.serde2.RegexSerDe'
with serdeproperties(
'input.regex'='(.*)\\|\\|(.*)',
'output.format.string'='%1$s %2$s'
)
stored as textfile;
2、加载数据
load data local inpath '/root/apps/hive-data/bi.dat' into table t_bi_reg;
3、测试结果是:
select * from t_bi_reg;
zs 24
ls 27
注:在数据量大的情况下上述方式比该方式效率高

Hive学习笔记一的更多相关文章

  1. hive学习笔记之一:基本数据类型

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  2. hive学习笔记之三:内部表和外部表

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  3. hive学习笔记之四:分区表

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  4. hive学习笔记之五:分桶

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  5. hive学习笔记之六:HiveQL基础

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  6. hive学习笔记之七:内置函数

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  7. hive学习笔记之九:基础UDF

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  8. hive学习笔记之十:用户自定义聚合函数(UDAF)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<hive学习笔记>的第十 ...

  9. hive学习笔记之十一:UDTF

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  10. Hive学习笔记(一)

    摘要: Hive 是建立在 Hadoop 上的数据仓库基础构架.它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储.查询和分析存储在 Hadoop 中的大规模数据的机制.H ...

随机推荐

  1. hdu3746 Cyclic Nacklace KMP

    CC always becomes very depressed at the end of this month, he has checked his credit card yesterday, ...

  2. hdu1540 Tunnel Warfare 线段树/树状数组

    During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast a ...

  3. java 调用process

    java调用process 有两种实现方法,一是使用Runtime类,二是使用Process类. 我在最近的项目里用的是Runtime类,接下来写下总结. 有图有真相(在网上学来一句话) packag ...

  4. 踩坑tomcat8.5的cookie机制

    https://www.pomelolee.com/1601.html tomcat升级到8.5版本 发现登录和退出报错,报错日志为下 [http-nio-8080-exec-20] 2016 Aug ...

  5. html2canvas用法的总结(转载)

    最近做h5网页,有个功能是用户能长按页面保存为图片,在我们理解就是网页要生成图片然后再让用户长按保存,然后就发现了html2canvas这个框架了,效果挺不错了,但是有几个坑说一下(用的最新版): h ...

  6. software download

    Develop Sourceinsight 3.50.0066 http://pan.baidu.com 这个版本支持输入文件名的一部分来查找文件,而不像3.50.0029必须输入完整的文件名 VFP ...

  7. [转]Java对象的序列化和反序列化

    一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存 ...

  8. MongoDB 设置账号和密码

    一.安装MongoDB 1.环境配置: i.操作系统:CentOS release 6.8 (Final) [root@iZ2ze2pbbffhmn53ao4tuaZ bin]# cat /etc/r ...

  9. Jenkins进阶-Slave 节点的配置(11)

    Jenkins的主节点无法满足当前的发布需求,所以我们需要增加一个从节点,我们是本着节约的模式,所以主从节点均需要有任务来进行构建: 1.系统管理->管理节点: 2.添加从节点,管理节点-> ...

  10. 运用MQTT-JMeter插件测试MQTT服务器性能

    今天我们介绍XMeter团队带来的新版MQTT-JMeter插件,您可以更为方便地添加MQTT连接.发布.订阅取样器,构造组合的应用场景,例如背景连接.多发少收.少发多收,计算消息转发时延等.利用该插 ...