1、hive简介
hive:由facebook开源用于解决海量结构化数据的统计工具。
hive是基于Hadoop的数据仓库工具,可以将结构化的数据文件映射为一张表,并提供sql查询功能。
2、hive本质
- hive的本质是HQL(HiveSQL)转化成MapReduce程序
- hive处理的数据存储在HDFS
- hive分析数据底层实现是MapReduce
- 执行程序运行在YARN
3、hive优缺点
优点:
- 操作接口采用类SQL语法,提供快速开发能力(简单,易上手)
- 避免去写MapReduce,减少开发人员的的学习成本
- hive优势在于处理大数据,对于处理小数据没有优势,hive执行延迟高
- hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数
缺点:
- hive执行延迟高,因此常用于数据分析,对实时性要求不高的场合
- hive的HQL表达能力有限
4、hive与数据库比较
查询语言:针对hive的特性设计了类SQL的查询语言,熟悉SQL的开发者可以方便的使用hive
数据更新:hive是针对数据仓库应用设计的,而数仓的内容读多写少,因此,hive中不建议对数据的改写,所有数据加载时确定好,而数据库中的数据通常是需要修改的,因此使用insert into添加数据,update修改数据。
执行的延迟:hive查询时由于没有索引,需要扫描整个表,因此延迟较高。另一个导致hive延迟较高的因素是MapReduce
数据规模:hive海量数据的支持,对应数据库处理数据量规模较小
5、hive操作
5.1 hive启动
hive
如果没有进入到hive,就执行以下步骤
cd /opt/module/apache-hive-2.1.1-bin/
bin/hive
如果拒绝连接
jps查看下集群,如果没有nameNode等,执行以下代码
cd /opt/module/hadoop-3.3.0/sbin/
./start-all.sh
hadoop集群启动
如果是安全模式则退出安全模式,查看5.6
5.2 hive退出
使用 exit;或者quit;
5.3 常用交互命令(设置成非严格模式,在当前会话生效)
-e 直接调用hiveSQL语句
hive -e “select * from test.emp”;
-f 调用文件中hiveSQL语句
vim hivef.sql
select * from test.emp;
hive -f /home/hadoop/123/hivef.sql > /home/hadoop/123/234/hivef.txt
5.4 在hive交互窗口了查看HDFS文件系统
dfs -ls /
5.5使用JDBC方式连接hive(用来启动DBeaver)
5.5.1 启动hiveserver2服务
screen -S hive --创建虚拟屏
hive --service hiveserver2 --启动服务
ctrl+a+d --退出虚拟屏
5.5.2 使用DBeaver连接hive
5.6 离开安全模式
查看安全模式
hdfs dfsadmin -safemode get
离开安全模式
hdfs dfsadmin -safemode leave
强制离开安全模式
hdfs dfsadmin -safemode forceExit
6、hive数据类型
基本数据类型
- TINYINT 1byte 有符号整数
- SMALLINT 2byte 有符号整数
- INT 4byte 有符号整数
- BIGINT 8byte 有符号整数
- BOOLEAN 布尔类型,TRUE或者FALSE
- FLOAT 单精度浮点数
- DOUBLE 双精度浮点数
- STRING 字符串
- TIMESTAMP 时间类型
集合数据类型
- STRUCT
- MAP
- ARRAY
实例演示
流程:在hive中test数据库下进行建表,linux中创建一个txt,放置表数据,然后把txt数据导入到hive表格中。
数据准备:
1、hive中进行建表;这个l_text会保存到/user/hive/warehouse/test.db/l_test
create table
l_test (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';
2、linux准备text.txt数据
注意最左边不要空格
fulaoshi,lilaoshi_luolaoshi,xiaofu:6_xiaofufu:5,ruyilu_guangzhou
lilaoshi,fulaoshi_luolaoshi,xiaoli:7,ruyilu_guangzhou
3、把linux中的text.txt数据导入到hive表格
load data local inpath '/home/hadoop/123/test.txt' into table test.l_test;
4、hive中进行数据查看
select * from l_test;
类型转化
隐式类型转换规则
1、任何整数类型都可以隐式转换为一个范围更广的类型,如TINYINT可以转换成INT,INT可以转换为BIGINT
2、所有整数类型,float和string(数字)类型都可以隐式转换为double
3、tinyint,smallint,int都可以转换为float
显示转换
cast(“1” as int )
select ‘1’+2,cast(‘1’ as int ) + 2;
7、DDL数据定义
7.1 创建数据库
create database test_2;
create database if not exists test_2;--加if not exists防止报错
- 指定HDFS路径(真实数据在HDFS上的存储路径)创建hive数据库;
create database test_a;
该数据库存储位置:/user/hive/warehouse/test_a.db
7.2 查看数据库
- 查看所有数据库
show databases;
- 查看指定数据库
desc database test;
desc database extended test;--更详细描述,有创建时间
7.3 修改数据库创建时间
- 修改数据库创建时间
alter database test_2 set dbproperties('createtime'='20230605');
7.4 删除数据库
- 删除空数据库
dorp database test_2;
- 判断数据库是否存在然后执行删除
drop database if exists test_2;
- 如果库不为空,强制删除
drop database test_2 cascade;
7.5 使用数据库
- 使用数据库
use databasename;
7.6 创建表
- 创建表
create table if not exists
external 外部表
comment 注释
partitioned by 分区
clustered by 分桶
sorted by 对桶中的数据排序
row format delimited fields terminated by ',' --指定列分隔符
collection items terminated by '_' --指定MAP STRUCT ARRAY的元素分隔符
map keys terminated by ':' --指定map中key和value的分隔符
lines terminated by '\n' --指定行分隔符
stored as 指定文件类型:textfile(文本),rcfile(列式存储格式文件),sequencefile(二进制序列文件)
as 后跟查询语句,根据查询结果创建表
like 允许用户复制现有表的结构,但不复制数据
7.6.1 管理表(内部表)
默认创建的表都是管理表(内部表)。hive会控制着数据的生命周期,当我们删除一个管理表(内部表)时,hive会删除这个表中的数据。(元数据和真实数据都会被删除)
管理表不适合与其他工具共享数据
(1)普通创建表
create table if not exists
hsstd (id int,name string)
row format delimited fields terminated by '\t'
stored as textfile
把数据导入到hsstd
load data local inpath '/home/hadoop/123/hsstd.txt' into table hsstd;
(2)根据查询结果创建表(查询的结果会添加到新创建的表中)
- 从hive的表格查询数据插入到hive表hsstd_2中
create table if not exists hsstd_2 as select id,name from hsstd where id<8;
- 删除表
drop table hsstd_2;
- 创建有分隔符的表
create table if not exists hsstd_2
row format delimited fields terminated by '\t'
as select id,name from hsstd where id<8;
- 根据已经存在的表结构创建表
create table if not exists hsstd_3 like hsstd;
- 查看表的类型
desc formatted hsstd;
7.6.2 外部表
因为表是外部表,所有hive认为并非完全拥有这份真实数据,删除该表并不会删除掉真实数据,不过描述表的元数据会被删掉。(删除元数据,保留真实数据)
实例:
(1)创建外部表
create external table if not exists
dept2(deptno int,dname string,loc int)
row format delimited fields terminated by '\t';
(2)删除外部表
drop table dept2;
7.6.3 内外表相互转换
内部表转换为外部表
alter table dept2 set tblproperties('EXTERNAL'='TRUE');
外部表转换为内部表
alter table hsstd_2 set tblproperties('EXTERNAL'='FALSE');
--FALSE可以替换成不会TRUE的值
7.7 修改表
- 添加列
alter table hsstd_2 add columns (age int);
- 更新列(重命名)
alter table hsstd_2 change column age age2 string;
- 替换列
alter table hsstd_2 replace columns (id int, name2 string, age string);
- 增加一列(如果上述进行替换列操作时,替换列少与原有列,相当与删除了部分列,但是增加列的时候,增加的列是原先删除列,原有列的数据会重新保留下来。个人猜测应该是替换列的时候元数据是保留了表数据的,所有添加的时候数据还会存在)
alter table xxx add columns (user_name string);
- 将增加的列放到某一列后面(换列的时候数据不会跟着动)
alter table xxx add columns (user_name string);
- 将增加的列放到第一列的位置
alter table xxx add columns (user_name string);
7.8 清除表中的数据(truncate)
只会删除管理表中的数据,不会删除外部表的数据
truncate table dept2;
8、DML数据操作
8.1数据导入(hive最小操作级别是文件级的,不能操作行,修改添加只会产生文件)
8.1.1向表中装载数据load
load date : 表示加载数据
local : 表示从本地加载到hive表,否则从HDFS加载到hive(加local是从linux,不加是从HDFS剪切)
inpath:加载数据的路径
overwrite:覆盖表中已有数据,否则追加
into table:表示加载到哪张表
partition:表示上传到指定分区
- 加载本地数据到hive
load data local inpath '/home/hadoop/123/hsstd.txt' into table test.hsstd;
- 上传文件到HDFS
hive中进行操作
默认上传到hdfs的/user/hadoop位置下
dfs -put /home/hadoop/123/hsstd.txt /hxx;
linux中进行上传
指定到了/shentu位置下
hadoop fs -put /home/hadoop/123/hsstd.txt /hxx
- 加载HDFS的文件到hive表中
load data inpath '/hxx/hsstd.txt' into table test.hsstd;
- 加载数据使用overwrite覆盖表中已有数据
load data local inpath '/home/hadoop/123/hsstd.txt' overwrite into table test.hsstd;
8.1.2 通过查询语句向表中插入数据(insert)
insert into table hsstd values (11,'hs11'),(12,'hs12');
insert overwrite table hsstd select id,name from hsstd where id<8;
8.1.3 多表(多分区)插入模式
from hsstd
insert overwrite table hsstd_3
select id,name
insert overwrite table hsstd_4
select id,name where id<5;
8.1.4 import导入(空表或不存在的表)
只有export导出的表目录才能使用import
1、先export导出现有表
export table hsstd3 to '/hxx/hsstd_dc3';
2、根据1中导出的目录,import导入新的表
import table hsstd5 from '/hxx/hsstd_dc3';
8.2 数据导出
(1)将查询结果导出到linux本地(无格式化)
insert overwrite local directory
'/home/hadoop/123/hsstd_dc3'
select * from hsstd;
(2)将查询结果格式化导出到Linux本地
insert overwrite local directory
'/home/hadoop/123/hsstd_dc4'
row format delimited fields terminated by '\t'
(3)将查询结果导出到HDFS
insert overwrite directory
'/hxx/hsstd_dc6'
row format delimited fields terminated by '\t'
select * from hsstd;
(4)export导出到HDFS上
export table test.hsstd to '/hxx/hsstd_dc2';
9、查询(这部分跟oracle差别不大)
9.1基本查询
9.1.1全表查询
select * from hsstd;
select id,name from hsstd;
9.1.2特定列查询
select name from hsstd;
注意
(1)大小写不敏感
(2)SQL可以写在一行或者多行
(3)关键字不能被缩写也不能分行
(4)各子句一般分行写
(5)使用缩进提高语句可读性
9.1.3列别名
select id as st_id,name from hsstd;
9.1.4算术运算符
+ - * / % & | ^ ~
select sal + 10000 from emp_2;
9.1.5 常用聚合函数
count sum min max avg
select count(*) cnt from emp_2;
9.1.6 where语句
select * from emp_2 where sal > 1000;
9.1.7比较运算符
A=B
A<=>B 如果A和B都为NULL则返回TRUE,如果一边为NULL返回FALSE
A<>B,A!=B
A<B
A<=B
A>B
A>=B
A NOT BETWEEN B AND C
A IS NOT NULL
A NOT IN (B,C)
select * from emp_2 where sal between 500 and 1000;
select * from emp_2 where mgr <=> comm;
select * from emp_2 where mgr is null and comm is null;
9.1.8 LIKE和RLIKE
RLIKE通过java实现正则表达式
select * from emp_2 where ename rlike '[A]';
select * from emp_2 where ename like '%A%';
9.1.9逻辑运算符
AND OR NOT
select * from emp_2 where sal > 1000 and deptno = 30;
select * from emp_2 where sal > 1000 or deptno = 30;
select * from emp_2 where deptno not in(20,30);
9.2分组
9.2.1 GROUP BY
select t.deptno,avg(t.sal) avg_sal from emp_2 t group by t.deptno;
9.2.2 HAVING
select t.deptno,avg(t.sal) avg_sal from emp_2 t group by t.deptno having avg(t.sal) > 2000;
9.3JOIN
- 内连接
只有进行连接的两个表中都存在与连接条件相匹配的数据才会被保留下来。(取交集)
select e.empno,e.ename,d.deptno,d.dname from emp_2 e join dept_2 d on e.deptno=d.deptno;
- 左外连接
JOIN操作符左边表中符合where子句的所有记录都会被返回。(左表为主表,驱动表。)
select e.empno,e.ename,d.deptno,d.dname from emp_2 e left join dept_2 d on e.deptno=d.deptno;
- 右外连接
JOIN操作符右边表中符合where子句的所有记录都会被返回。(右表为主表,驱动表。)
select e.empno,e.ename,d.deptno,d.dname from dept_2 d right join emp_2 e on e.deptno=d.deptno;
- 满外关联
将会返回所有表中符合where条件的所有记录,如果任一表的指定字段没符合条件的话,那么使用NULL替代。
select e.empno,e.ename,d.deptno,d.dname from emp_2 e full join dept_2 d on e.deptno=d.deptno;
- 多表连接
select e.ename,d.dname,l.loc_name
from emp_2 e
join dept_3 d
on e.deptno=d.deptno
join location_2 l
on d.loc=l.id;
- 笛卡尔积
在下面条件下产生
(1)省略连接条件
(2)连接条件无效
(3)所有表中的所有行相互连接
select e.empno,e.ename,d.deptno,d.dname from emp_2 e,dept_2 d;
9.4排序
9.4.1全局排序(order by)
order by:全局排序,只有一个Reduce(效率不高,都在一个reduce里面)
可以升序(默认)ASC、降序DESC、可以使用字段别名进行排序,因为执行顺序在select之后
select * from emp_2 order by sal;
select ename,sal * 2 twosal from emp_2 order by twosal desc;
9.4.2每个reduce内部排序(sort by + 加排序的字段)
- 查看reduce数量:
set mapreduce.job.reduces;
- 设置reduce数量:
set mapreduce.job.reduces=3;
- 加载sort by结果到本地
insert overwrite local directory
'/home/hadoop/123/sortby-result'
row format delimited fields terminated by '\t'
select * from emp_2 sort by deptno desc;
9.4.3分区(distribute by)
在有些情况下,需要控制某个特定的行进入指定reducer,为了后续的操作,结合sort by使用
- 查看reduce数量:
set mapreduce.job.reduces;
- 设置reduce数量:
set mapreduce.job.reduces=3;
insert overwrite local directory
'/home/hadoop/123/sortby-result2'
row format delimited fields terminated by '\t'
select * from emp_2 distribute by deptno sort by empno desc;
9.4.4cluster by
当distribute by和sort by字段相同时,可以使用cluster by 只能正序
- 查看reduce数量:
set mapreduce.job.reduces;
- 设置reduce数量:
set mapreduce.job.reduces=3;
- 实例:
insert overwrite local directory
'/home/hadoop/123/sortby-result3'
row format delimited fields terminated by '\t'
select * from emp_2 cluster by deptno;
—明天更新剩下的