hive数据仓库之学习笔记(二)

内部表

内部表是未被 “external” 修饰的表,其由 hive 管理。内部表由于存储了元数据以及存储数据,所以删除内部表,存储数据与元数据也会被删除。并且内部表被创建得路径在 hive 的默认仓库目录,即 “ /user/Hive/warehouse/”

create external table student06(
	id int,
    name string,
    age int) row format delimited fields terminated by '\t';

外部表

外部表是被 “external” 修饰的表,其由 HDFS 管理。删除外部表仅仅会删除元数据,但是存储数据不会被删除。用户在创建外部表时,可以自己指定表的路径:

create external table student06(
	id int,
    name string,
    age int)
    location '/dblocation02';

内、外部表总结

内部表 外部表
目录由 hive创建在默认的目录下 目录由用户自己创建表时自己用 location 来指定
删除表时,表的元数据与表的数据目录都会被删除 删除表时,只删除表的元数据而表的数据不会被删除

一般来源的数据会在不同的平台上进行处理,所以为了方便映射,就可以采用 外部表来进行映射,这样即使删除掉了表,也不会删除数据。也就不会影响数据在其他平台上的处理了。

分区表

分区表是在系统下创建文件夹目录,把分类数据放在不同的目录里面,可以加快查询速度。

如: 创建一个以 age 分区的表,

create table student08(
	num int,
    name string
    )PARTITIONED BY (age string) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t";

//导入分区数据
LOAD DATA INPATH '/stud.txt' OVERWRITE INTO TABLE student08 PARTITION (age='7');

// 增加表分区
alter table student08 add partition(age='9') partition(age='15');

// 查看表分区
show partition tableName;

// 导入分区数据
insert into student08 partition(age='11');

select * from student08 where age='9';

// 删除表分区  --  子目录和数据都会被删除
alter table tableName drop partition(day='11');

分区表中,表目录里面有多个子目录。如果要针对不同时间,格式等要求创建表,那么可以创建分区表,没有必要创建多个表。

分区表的数据是存放在不同的子目录中,在查询的时候,既可以针对子目录进行扫描,也可以针对全表进行扫描。

创建分区表后,分区目录看不到子目录,只有在导入数据才可以看到。

数据的导入与导出

load

  1. 从本地导入
load data local inpath 'local_path' into table tb_name; 
  1. 从 HDFS 导入
load data inpath 'hdfs_path' into table tb_name;

// overwrite: 覆盖, 用于临时表
load data inpath 'hdfs_path' overwrite into table tb_name;

两者的不同主要是本地导入,需要加 “local” 关键字,不加 “local”,就是 HDFS 的导入加载。

as 查询输出

  1. 将从 tb1 的查询结果保存到 tb 上
create table tb_name as select * from tbl_name;
create table tb as select * from tb1

insert into 追加,导出

  1. 将从 tb1 上查询的结果追加到 tb 上
insert into table tb_name select * from tb1_name;
  1. 将从 tb1 上查询的记过覆盖到 tb 上。注意:这里有一个 overwrite 关键字。
insert overwrite table tb_name select * from tb1_name;
  1. 将 tb 上查询到的数据导出到 hdfs 上
insert overwrite directory 'hdfs_path' select * from tb_name;
  1. 将 tb 上查询到的数据导出到本地上
insert overwrite [local] directory 'path' select * from tb_name; //导出到本地
insert overwrite [local] directory 'path' row format delimited fields terminated by '\t' select * from tb_name; //数据之间会有制表空格

insert overwrite directory  '/bb'  select * from student08;
insert overwrite local directory '/bb' select * from student08;  // 导出到本地

location 导入

  1. 将指定的本地文件导入到外部表中,或者管理表中对数据的指定
dfs -put local_file_path hdfs_table_name;

eg: 
dfs -put /opt/app/dep2.txt /user/hive/warehouse/dp.db/dept

hdfs -put local_path hdfs_path;   // hdfs 提交文件
hdfs -get hdfs_path local_path;   //导出到本地
hive -e                           //将输出重定向保存到本地文件
hive -f                          //将输出重定向保存到本地文件

import& export

export table tb_name to 'hdfs_path';    //将数据导出来, 必须是一个空目录
import table tb_name form 'hdfs_path'; //将数据导入到数据库

Sqoop

涉及到 sqoop,等待 sqoop 操作再写。

Hive 函数分析

COUNT, SUM, MIN, MAX, AVG

扫描二维码关注公众号,回复: 6394087 查看本文章

lag 和 lead 有三个参数,第一个参数为列名,第二个参数是偏移的 offset,第三个参数是c超出记录窗口时的默认值。
LEAD(col, n, DEAFAULT) //用于统计窗口内往上第 n 行值

select lead(age) over(order by name) from student02;
select lead(age,2,0) over(order by name) from student02;

LAG(col, n, DEAFULT) //用于统计窗口内往下第 n 行值.

select lag(age) over(order by name) from student02;
select lag(age,2,0) over(order by name) from student02;

常用 HQL

过滤: where / limit / distinct (唯一查询) / between and / is null / is not null / case when then
select * from tb_name where name = 'add';
select * from tb_name limit 10, 1    // (从10开始(但不包括10), 选取 1 个)—
selct * from tb_name limit limit 2    //(选取 2 个);

select distinct name from tb_name;   //唯一的name取出
select * from tb_name where name between 'aaa' and 'bbb'
select * from tb_name where name is null;
select * from tb_name where name is not null;

select * , (case sex when 1 then 'man' when 2 then 'women' else '' end) from tb_name;
select *, (case name when 'zhang01' then 'xxxx' when 'zhang02' then 'zzzz' else '' end) from student02;

聚合: count / sum / avg / max / min / group by / having   //(必须有 group by) 
select avg(col1 * col2) from tb_name;
select sum(col1) from tb_name;
select count(*) from tb_name where col1 >100;
select min(col1 * col2) from tb_name;
select max(col1 * col2) from tb_name;

select * from tb_name group by col_name;
select name,num,collect_set(age) from student02 group by name;

//SELECT student_class,COUNT(ALL student_name) AS 总人数 FROM t_student GROUP BY (student_class);

 //select * from tb_name having col1 >20 
select age, collect_set(name,num) from student02 group by age  having age > 8;
//SELECT student_class,AVG(student_age) AS 平均年龄 FROM t_student GROUP BY (student_class) HAVING AVG(student_age)>20; 
   
多表之间 inner join / 多表之间 left join / 多表之间 right join / 多表之间 full join
select * from tb1_name inner join tb2_name on tb1.colname = tb2.colname;  //两表的交集.

// LEFT JOIN产生表1的完全集,而2表中匹配的则有值,没有匹配的则以null值取代。
select colname(s) form tb1_name left join tb2_name on tb1.colname = tb2.colname; 

// RIGHT JOIN产生表2的完全集,而1表中匹配的则有值,没有匹配的则以null值取代
select colname(s) form tb1_name right join tb2_name on tb1.colname = tb2.colname;

//FULL OUTER JOIN产生1和2的并集。但是需要注意的是,对于没有匹配的记录,则会以null做为值 
select colname(s) form tb1_name full join tb2_name on tb1.colname = tb2.colname;  

// 导入
load data local inpath '/a1.txt' into table student08 partition (age='11');
load data local inpath '/a1.txt'  overwrite into table student08 partition (age='15'); // 覆盖
load data inpath '/a.txt' into table student08;  // 从 hdfs 上的 a.txt 导入

HQL 执行顺序

– 第一步:执行 FROM
– 第二步:WHERE 条件过滤
– 第三步:GROUP BY 分组
– 第四步:执行 SELECT 投影列
– 第五步:HAVING 条件过滤
– 第六步:执行 ORDER BY 排序

Hive 运行参数

// 设置每个 reduce 处理的数据量hive.exec.reducers.bytes.per.reduce=

// 设置最大能够运行的 reduce 个数
hive.exec.reducer.max=

// 实际 reduce 的个数
mapreduce.job.reduces=

// 设置 reduce 开启条件
hive.fetch.task.conversion=fertchtask / mapreduce

排序方式

  • order by 全局排序
    order by 会对查询的全局结果进行排序。最终 map 数据的数据汇聚到一个 reduce 中去执行。如果数据量很大,那么这个操作是相当漫长的。所以在 hive 操作中尽量少用 order by,除非数据量很小。
select * from student08 order by age;
  • sort by 局部排序
    sort by 是一个局部排序,也就是说在每个 reduce 中进行排序,保证每个reduce 中的数据是有序的。但是对于全局而言,其又不一定是有序的。
select * from student08 sort by age;
  • distribute by 分区
    distribute by 是指定输出结果怎样划分到各自的 reduce 分区中。
    eg:指定 age 字段相同的结果被划分到同一个 reduce分区中。
select * from student08 distribute by age;
  • cluster by = sort by + distribute by
    cluster by 具有 sort by 与 distribute by 的两重功能。能将相同字段进行 sort by 排序和distribute by 分区。
select * from student08 cluster by age;
select * from  student08 distribute by age sort by age;

自定义函数 UDF

  1. 配置环境 pom / hive-site.xml
  2. 自定义类继承 org.apache.hadoop.hive.ql.exec.UDF
    定义 public Object evaluate(Object args) 方法
  3. 导出 jar 包并植入本地环境 linux 的 localpath 目录下
  4. 关联 jar, 进入hive add jar localpath;
  5. 创建临时函数 create temperary function 函数名 as ‘包名.类名’;
  6. 执行
public class UserInfoParser extends UDF{
	public String evaluate(String field,int index){
	String replaceAll = field.replaceAll("\\|", " ");
	String[] split = replaceAll.split(" ");
	return split[index-1];
	}
}

// 创建临时函数 
create temporary function functionName as 'packageName.className';

虚拟列

虚拟列并不是在表中真正存在的列,其用意是为了将 hive 中的表进行分区,这对每日增长的海量数据存储而言非常有用的。

其种类有两种:

  1. 这行数据属于哪个文件 ---- INPUT__FILE__NAME
  2. 块的偏移量,类似于每行的存储地址 ---- BLOCK__OFFSET__INSIDE__FILE
select *, INPUT__FILE__NAME from student;
select *, BLOCK__OFFSET__INSIDE__FILE from student;

猜你喜欢

转载自blog.csdn.net/dec_sun/article/details/90274755