Hive-数据仓库

数据仓库

概念

数据仓库是一个面向主题的,集成的,相对稳定的。反应历史变化的数据集合,用于支持决策
主题:把不同数据库和用户相关的数据抽取在一起
集成:进行合并
相对稳定:不是实时的(因为数据量太大,影响网站运行效率),一般按天对数据进行抽取,合并
反应历史变化:用来统计,进行管理决策
在这里插入图片描述

传统数据库面临的挑战(不足)

1.无法满足快速增长的海量数据的存储需求
2.无法有效处理不同类型的数据
3.计算和处理能力不足

hive

官网:http://hive.apache.org/

简介

Hive是基于Hadoop的数据仓库,他提供工具用来ETL ,可以存储,查询,分析在hadoop上的大规模的数据。

Hive可以将结构化的数据文件映射成一张数据库表,使用类sql语句将其转换成MR作业进行运行。

学习成本低,非常适合熟悉sql的用户。

也允许熟悉MR的人自定义MR

why

为什么有良好的可扩展性:hdfs可以很简单的奴役新的datanode节点

为什么可以看成是用户的编程接口:hive只是将输入进来的类sql语句转换成MR,它并没有存储和处理数据的过程

为什么Hive采用批处理处理数据:因为底层是MR

为什么Hive只适合处理静态的数据:因为底层MR只是处理离线数据

Hive和Hadoop中其他组件的关系

在这里插入图片描述

Hive和传统数据库的区别

1.Hive和关系型数据库的存储文件的系统不同
hive存储文件的系统是hdfs。
关系型数据库是将文件存到本地。
2.hive的计算模型是MR,关系型数据库是自身的计算模型。
3.hive不适合用于小数据的存储,因为他的存储是hdfs,hdfs的namenode存放目录,当有很多小文件的时候目录就会很大。
4.hive的实时性差因为MR是离线处理系统
5.hive的扩展性会比传统数据库强的多,因为hdfs可以很容易的奴役新的数据节点
6.Hive不支持时间或行级更新,因为hdfs是一次存入多次读取,hdfs不支持修改
在这里插入图片描述

总结

Hive是由Facebook开源用于解决庞大的结构化日志的数据统计。
hive可以将结构化的数据文件映射为一张表,提供类sql查询功能
本质:是将HQL转化成MR程序
hive存储数据在hdfs,计算在MR,执行在Yarn

优点

1.简单易上手
2.Hive执行延迟高,常用于数据分析,对实时性要求不高的场景
3.hive优势在于处理大量的数据
4.hive支持自定义函数

缺点

1.hive的hql的表达能力有限
1)迭代式算法无法表达
2)数据挖掘方面不擅长
2.hive的效率比较低
1)hive生成的MR通常不够智能化
2)调优比较难,粒度较粗

hive和hdoop的关系

在这里插入图片描述

hive 的架构

在这里插入图片描述
提交:CLI,JDBC,ODBC
元数据:存放在hdfs的哪个目录。。。。

在这里插入图片描述

hive的安装

hive有三种运行模式:单机,伪分布式,完全分布式

安装mysql

1.将mysql的安装包上传到linux上
2.删除原有的mysql
rpm -qa | grep mysql
rpm -e --nodeps mysql
3.解压mysql安装包
tar -xzvf 安装包名
4.将mysql移动到/usr/local路径下
mv /home/hduser/software/mysql /usr/local
5.增加用户组mysql
sudo groupadd mysql
6.在mysql用户组中创建新的用户mysql
sudo useradd -g mysql mysql
7.修改目录拥有者
sudo chown -R mysql:mysql mysql
8.增加环境变量:
在/etc/profile最下方增加

export MYSQL_HOME=/usr/local/mysql
export PATH=$PATH:$MYSQL_HOME/bin

9.初始化mysql
在mysql的目录下
sudo scripts/mysql_install_db --user=mysql
10.启动mysql
sudo ./support-files/mysql.server start
11.查看是否启动
ps -ef|grep mysql
12.进入mysql
mysql -u root
13.给root加密码
use mysql;
update user set password=PASSWORD(‘admin’) where user=‘root’;
flush privileges;
exit;
14.修改编码方式
1)查看mysql编码方式 status
2)如果发现有的编码方式是latin1需要修改
3)修改配置文件
sudo vim my.cnf
在[mysqld]下添加:
character-set-server=utf8
4)重启mysql
sudo ./support-files/mysql.server restart
再次进入mysql
status,看编码全是utf8就OK

安装hive

1.首先将hive安装包上传到linux系统中
2.解压hive安装包
3.配置hive环境变量
在/etc/profile最下方增加

export HIVE_HOME=/home/hduser/software/hive-1.2.1
export PATH=$PATH:$HIVE_HOME/bin

4.配置hive-site.xml文件
1)首先将 hive-env.sh.template更名为hive-env.sh
2)在hive-env.sh中修改,添加

HADOOP_HOME=/home/hduser/software/hadoop-2.7.2
HADOOP_CONF_DIR=/home/hduser/software/hadoop-2.7.2/etc
export HIVE_CONF_DIR=/home/hduser/software/hive-1.2.1/con
export HIVE_AUX_JARS_PATH=/home/hduser/software/hive-1.2.1/lib

5.启动hive
hive(hive在哪个目录下执行,哪个目录下就会生成一个元文件 metastore_db)

将元数据存到mysql中

将mysql-connection-java.jar上传到hive的lib文件夹中
在hive的conf文件夹中创建hive-site.xml文件
在其中配置:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
	<property>
	  <name>javax.jdo.option.ConnectionURL</name>
	  <value>jdbc:mysql://testmachine:3306/metastore?createDatabaseIfNotExist=true</value>
	  <description>JDBC connect string for a JDBC metastore</description>
	</property>

	<property>
	  <name>javax.jdo.option.ConnectionDriverName</name>
	  <value>com.mysql.jdbc.Driver</value>
	  <description>Driver class name for a JDBC metastore</description>
	</property>

	<property>
	  <name>javax.jdo.option.ConnectionUserName</name>
	  <value>root</value>
	  <description>username to use against metastore database</description>
	</property>

	<property>
	  <name>javax.jdo.option.ConnectionPassword</name>
	  <value>admin</value>
	  <description>password to use against metastore database</description>
	</property>
</configuration>

之后启动mysql,启动hadoop,最后启动hive

HiveJDBC访问

1.首先启动 hiveserver2
2.在另一个连接中启动beeline
3.在beeline中输入
!connect jdbc:hive2://linux8:10000
username hduser
password 回车

Hive常用交互命令

1.-e 不进入hive交互窗口执行命令
hive -e “show databases;”
2. -f 执行文件脚本中的sql命令
hive -f ./text

其他命令

1.退出hive窗口
exit;先提交数据在退出
quit;直接退出
2.在hive窗口中查看hdfs文件系统
dfs -ls
3.在hive窗口中查看本地文件系统
! ls ./
4.查看hive中输入的历史命令
cat .hivehistory

hive常见属性配置

1.修改default数据仓库的原始位置,
在hive-default.xml.template中有

<property>
	<name>hive.metastore.warehouse.dir</name>
	<value>/user/hive/warehouse</value>
</property>

将其复制到hive-site.xml中,之后改value
2.显示当前数据库,查询表头信息配置
在hive-site.xml中添加配置

<property>
	<name>hive.cli.print.header</name>
	<value>true</value>
</property>

<property>
	<name>hive.cli.print.current.db</name>
	<value>true</value>
</property>

hive-hql常用命令

1.查看所有数据库名

show databases;

2.创建数据库

create database pgdb;

3.查看数据库的属性

desc database extended pgdb;

4.删除数据库

drop database pgdb
drop database pgdb cascade(级联删)

5.创建一张以\t为分隔的表

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

6.查看表结构

desc tb1;

7.修改表名

alter table tb1 rename to tb2;

8.增加字段

alter table tb2 add columns(age int);

在创建表的时候可能会有错误:

FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException(message:For direct MetaStore DB connections, we don't support retries at the client level.)

解决方法:进入mysql,把初始数据库的字符集改成latin1;

ALTER DATABASE metastore CHARACTER SET latin1

就OK了
9.克隆表(备份)

create table stu2 as select id,name from stu;

10.复制表结构

create table stu3 like stu2

11.添加数据
本地数据: load data local inpath '路径' into table 表名
hdfs上的数据:load data inpath '路径' into table 表名
12.删除包保留表结构

truncate table tb1;

13.模糊查询

show databases like 'pg*';

14.加注释

alter table tb1 add columns(name string comment 'user name');

15.避免要创建的数据库已存在的错误

create databases if not exists pgdb;

16.查看表的详细数据

desc formatted stu;
管理表(内部表)

1.hive对表和数据的生命周期进行全程的管理
2.在创建表的时候不特别指定就是创建管理表
3.删除表的时候,里面的数据也会被删掉
4.添加数据的时候会将数据放入表目录下

外部表

1.hive不管理数据,只管理元数据
元数据:metastore中的数据
数据:表目录中的数据
2.删除表的时候只删除元数据,不删除数据
3.创建外部表

create external table stu(id int)row delimited fields terminated by '\073'(\073表示;) location '路径'

分区表

1.创建分区表
1)

create table par_tb(name string,nation string) partitioned by(gender string) row format delimited fields terminated by ',';

2)`

create table par_th1 like par_tb;

2.通过分区表创建普通表

create table par_pp as select name,nation,gender from par_th1;

(有数据)
3.向分区表中静态添加数据
1)

load data local inpath '路径' into table par_th1 partition(gender='boy');

4.向单分区中动态添加数据

insert overwrite table par_stu1 partition(gender) select name,nation,gender from par_dum_stu;

注:par_dum_stu:有数据的无分区表
par_stu1:无数据的有分区表
5.向有多分区的表中动态添加数据

insert overwrite table par_stu1 partition(gender='women',year) select name,nation,year from par_stu2;
insert overwrite table par_stu1 partition(gender,year) select name,nation,year from par_stu2;

partition动态添加多分区数据的时候,
可以是第一个分区静态添加,第二个分区动态添加
可以是两个分区都是动态
6.增加分区

alter table par_tb1 add partition(year='1092') 

注:增加的分区必须是已有的分区字段,且这个字段的分区不能存在
7.删除分区

alter table par_tb1 drop partition(year='1021')

8.查看分区详情

 show partitions 表名;

9.手动加载数据
1) 首先在hdfs的表所在的文件夹中添加文件夹

 dfs -mkdir -p ‘路径’;

在文件夹中上传数据

 dfs -put ‘路径’ ;

刷新数据库

msck repair table 表名;

2)首先在hdfs的表所在的文件夹中添加文件夹

 dfs -mkdir -p ‘路径’

在文件夹中上传数据

 dfs -put ‘路径’ 

创建–声明分区

 alter table 表名 add partition(year='1000');

3)首先在hdfs的表所在的文件夹中添加文件夹

 dfs -mkdir -p ‘路径’

load 加载数据

总结:

分区的目的是为了更高效的查找数据
当按照分区字段去查找数据的时候,会直接去分区的文件夹中取数据,所以会更快

数据导入–将数据导入hdfs

load data local inpath ‘路径’ overwrite into table student partition(gender='men')

2.插入一条数据

insert into table student partition(mouth='202004') value('1004',wangwu);

3.根据单表查询结果

insert overwrite table student partition(mouth='202004')
select id,name from student where mouth='202004'

4.插入多条数据

from student
insert overwrite table student partition(mouth='202004')
select id,name where mouth='202004'
insert overwrite table student partition(mouth='202005')
select id,name where mouth='202005'

5.创建表时通过Location指定加载路径

create table stu3(id string,name string) row format delimited fields terminated by '\t' location 'hdfs路径'`

之后将数据手动上传到此目录中
6.import导入到本地
注:只有用export导出的数据才能用import导入

import tablestudent from ‘hdfs路径’

数据导出–将数据导入本地

1.将查询的结果导出到本地

insert overwrite local directory ‘本地路径’ select * from student

2.将查询结果格式化导出到本地

insert overwrite local directory '本地路径' row format delimited fields terminated by '\t' collection items terminated by '\n' select * from student

3.将结果导出到hdfs

insert overwrite  directory '本地路径' row format delimited fields terminated by '\t' collection items terminated by '\n' select * from student

4.hadoop命令导出

dfs -get hdfs路径 本地路径

5.hive shell命令导出

bin/hive -e 'select * from default.student;'>本地路径

6.export 导出到hdfs

export table default.student to ‘本地路径’

HQL语法

1.和sql一样,不区分大小写
2.语句可以换行,但是关键字不能拆开写

列别名

select saraly as saralyy from emp

后面的是别名

select saraly saralyy from emp

算数运算符

在这里插入图片描述

比较运算符

在where子句中使用
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

like,rlike

select * from emp where saraly like ‘2%’ 查询以2开头的字段
select * from emp where saraly like ‘[2]’查询字段中有2的字段

between and
select * from emp where saraly between 1000 and 5000

between后面的数不能比and后面的数大

limit子句

select * from emp limit 5 显示前5行

聚合函数

count

计数
count(1)显示有几行
count(*)显示有几行

max min

求这一列的最大值最小值

select max(saraly) from emp
select min(saraly) from emp
sum

求和

select sum(saraly) total from emp
avg

求平均值

select avg(saraly) total from emp

分组–group by

分组查询的关键字:每个
分组就是将分组字段中相同的值分成一组进行操作
分组查询显示的字段只能是分组字段或者是聚合函数
查询每个部门的平均工资:

select dep,avg(saraly) from emp group by dep

having

常和group by 连用
group by需要在having的前面
查询薪水大于2000元的部门的平均工资

select dep,avg(saraly) avg_saraly from emp group by dep having avg_saraly>2000

表连接

内连接

内连接就是将连接字段相匹配的字段全部输出

select * from emp e join dept d on e.dept_on=d.dept_on
左外连接

在join前的表是左表,在join后的表是右表,左连接就是把左表当做主表,将每行数据和右表的所有数据进行匹配,匹配成功就输出,如果没有与之匹配的项就将次表数据的填成null

select * from emp e left join dept d on e.dept_on=d.dept_on
右外连接
select * from emp e right join dept d on e.dept_on=d.dept_on
满外连接

满外连接就是将左连接和有连接的值合并

select * from emp e full join dept d on e.dept_on=d.dept_on

排序

Order by

全局排序:只起一个reducetask
写在select 语句后
select * from emp order by saraly

sort by

改变reducetask的数量:set mapreduce.job.reduces=3;
区内有序:每个reduce task里的数据分别有序
select * from emp sort by saraly

distribute by

相当于MR中的partition,但是区内无序,需要和sort by配合使用。
select * from emp distribute by emp_no sort by emp_on;

cluster by

当distribute by和sort by 的值相同的时候 可以直接用
cluster by 代替
select * from emp cluster by emp_no

分桶

分桶表数据存储

分区是针对数据的存储路径,分桶是针对的数据文件。
分桶是将数据集分解成更容易管理的若干部分的技术

分桶表建立
create table  stu_buck(id int,name string) clustered by(id)
into 4 buckets
row format delimited fields terminated by '\t';

查看详细表结构

desc formatted stu_buck;

在向分桶表插入数据的时候需要设置一个属性:

set hive.enforce.bucketing=true;
set hive.mapreduce.job.reudces=-1;(默认)
分桶抽样查询
select * from stu_buck tablesample(bucket 1 out of 4 on id);

语法结构是:
tablesample(bucket x out of y)
解释: 例如分桶个数n 为4,当x等于1,y等于4的时候效果就是在第一个桶取一桶的数据
取多少数据:n/y
在哪开始取:x
y只能取n的整数倍,或者n的因子
x不可以比y大

数据块抽样

这个是基于行数,按照数据块百分比进行抽样

select * from stu tablesample(10 percent);

这句的意思就是在这个桶中取10%的数据

注:

hive函数

行转列查询

集合数据类型:
struct:可存不同的数据类型
map:以键值的方式存储
array:只能存储一种数据类型
例:

 create table person_info(name string,friends array<string>,children map<string,int>,address struct<street:string,city:string>) row format delimited fields terminated by ',' collection items terminated by '_' map keys terminated by ':' lines terminated by '\n';

array和map在声明数据类型的时候需要在尖括号中声明
collection items terminated by 是声明每个array和map中每项的分隔符(必须写)
map keys terminated by 是声明map中键值对的分隔符

查询集合数据类型
查询array

通过字段名[下角标]查询

select friends[1] from person_info where name='zhangfei';
查询map

通过字段名[key值]

select children['cao zhi'] from person_info where name='caocao';
查询struct
select adress.street from person_info where name='zhangfei';
函数类型

udf 一进一出 例:转换大小写的函数
udaf 多进一出 例:max,min,avg
udtf 一进多出 例:explode

合并函数(聚合函数)

只能合并string类型的字段

concat

这个函数是将字符连接在一起

select concat('hello','world');
concat_ws

这个函数是concat的进阶版,第一个字符代表分隔符

select concat(',','hello','world');
collect_set

这个函数的作用就是去重之后将去重后的数据整合在一个array中

select collect_set(字段名) from 表名;
炸裂函数
explode

此函数是将hive中复杂的类型拆开

select explode(字段名) from 表名
lateral view

将炸裂开的字段映射成一个视图并且和原表的数据的关联依然存在

select  movie,movie_type  from movie lateral view explode(字段名) table_tmp as movie_type;
nvl

判断是否为空
select nvl(字段名,默认值)from 表名

分析函数

分析函数又叫窗口函数,主要是用来数据统计分析的
hive 的分析函数包括 LEAD,LAG,FIRST_VALUE,LAST_VALUE,RANK,ROW_NUMBER,PERCENT_RANK,CUBE,ROLLUP

查看分析函数

show function;
详细查看某个分析函数:desc function substr;

over

over(),将所有行放入窗口
窗口:进行处理的行
指定分析函数工作的数据窗口大小,其中可以用partition by 字段 进行分组,可以用order by 字段名 进行排序

partition by

partition by 的作用就是将窗口的大小控制为每个分组的大小。
例:购买过的顾客及总人数

select * ,sum(cost) over(partition by name)  from bussiness 
order by

order by作用就是排序,将窗口的大小从第一行开始加,一直加到最后

select *,sum(cost) over(order by order_date) from bussiness;
current row

当前行

n preceding

往前n行
select * ,sum(cost)

n following

往后n行

unbounded

起点

unbounded preceding

表示起点

unbounded following

表示终点

LAG(col,n)

往前n行
例:查询用户上一次的购买时间

select * lag(order_data,1) over( partition by name order by order_data) from bussiness;
LEAD(col,n)

往后n行
例:查询用户下一次的购买时间

select * lead(order_data,1) over( partition by name order by order_data) from bussiness;
ntile(n)

把有序分区中的行分发到指定数据的组中各个组有编号,编号从一开始,对于每一行,ntile返回此行所属的组 。
例:查询前20%的数据

select * from (select * ntile(5) over(order  by order_date) group_id from bussiness) t where group_id=1;

在这里插入图片描述

rank()

排序的时候,当遇到两个值相等的时候序号会重复,总数不变
select * rank() over(partition by name order by score)

dense_rank()

排序的时候,当遇到两个值相等的时候序号会重复,总数会变少

row_number()

会把行号变成序号

自定义函数

首先在idea的maven项目中的pom.xml文件下,加载jar包

<dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-exec</artifactId>
            <version>3.1.2</version>
</dependency>

之后创建一个类让其继承UTF类
写一个public方法

public  String evaluate(String a){
        return "Hello"+a;
    }

之后打包
上传到linux上
打开hive
增加jar包

add jar 路径名

注册函数

create temporary function 自定义函数名 as "主类路径";
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值