1)Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类 SQL 查询功能。
2)Hive 本质:将 HQL 转化成 MapReduce 程序;
Hive 处理的数据存储在 HDFS
Hive 分析数据底层的实现是 MapReduce
执行程序运行在 Yarn 上
3)Hive 架构原理
1)把 apache-hive-3.1.2-bin.tar.gz 上传到 linux 的/opt/software 目录下
2)解压 apache-hive-3.1.2-bin.tar.gz 到/opt/module/目录下面
[atguigu@hadoop102 software]$ tar -zxvf /opt/software/apache-hive-3.1.2-bin.tar.gz -C /opt/module/
3)修改 apache-hive-3.1.2-bin 的名称为 hive
[root@node01 module]# mv apache-hive-3.1.2-bin/ hive
4)修改/etc/profile.d/my_env.sh,添加环境变量
[root@node01 hive]# sudo vim /etc/profile.d/my_env.sh
添加内容
#HIVE_HOME
export HIVE_HOME=/opt/module/hive
export PATH= P A T H : PATH: PATH:HIVE_HOME/bin
5)解决日志 Jar 包冲突
[atguigu@hadoop102 software]$ mv $HIVE_HOME/lib/log4j-slf4j-impl2.10.0.jar H I V E H O M E / l i b / l o g 4 j − s l f 4 j − i m p l − 2.10.0. b a k 6 ) 初 始 化 元 数 据 库 [ a t g u i g u @ h a d o o p 102 h i v e ] HIVE_HOME/lib/log4j-slf4j-impl-2.10.0.bak 6)初始化元数据库 [atguigu@hadoop102 hive] HIVEHOME/lib/log4j−slf4j−impl−2.10.0.bak6)初始化元数据库[atguigu@hadoop102hive] bin/schematool -dbType derby -initSchema
hdp.sh start
myhadoop.sh start
1)启动 Hive
[atguigu@hadoop102 hive]$ bin/hive
2)使用 Hive
hive> show databases;
hive> show tables;
hive> create table test(id int);
hive> insert into test values(1);
hive> select * from test;
1)检查当前系统是否安装过 MySQL
[atguigu@hadoop102 ~]$ rpm -qa|grep mariadb mariadb-libs-5.5.56-2.el7.x86_64
//如果存在通过如下命令卸载
[atguigu @hadoop102 ~]$ sudo rpm -e --nodeps mariadb-libs
2)将 MySQL 安装包拷贝到/opt/software 目录下
3)解压 MySQL 安装包
[atguigu @hadoop102 software]# tar -xf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar -C /opt/module/
4)在安装目录下执行 rpm 安装
[atguigu @hadoop102 software]$
sudo rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm --nodeps --force
备注:[atguigu@hadoop102 software] yum install -y libaio
5)删除/etc/my.cnf 文件中 datadir 指向的目录下的所有内容,如果有内容的情况下:
查看 datadir 的值: [mysqld] datadir=/var/lib/mysql
删除/var/lib/mysql 目录下的所有内容:
[atguigu @hadoop102 mysql]# cd /var/lib/mysql
[atguigu @hadoop102 mysql]# sudo rm -rf ./* //注意执行命令的位置
6)初始化数据库
[atguigu @hadoop102 opt]$ sudo mysqld --initialize --user=mysql
7)查看临时生成的 root 用户的密码
[atguigu @hadoop102 opt]$ sudo cat /var/log/mysqld.log
1.内部表、外部表操作
内部表(管理表):创建表时如果没有使用external关键字;
外部表:外删除hive表的时候,数据仍然存放在hdfs当中,不会删掉。不过描述表的元数据信息会被删除掉。
2.排序
order by:会对输入做全局排序,因此只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。
sort by:每个MapReduce内部进行排序,对全局结果集来说不是排序。
distribute by:在有些情况下,我们需要控制某个特定行应该到哪个 reducer,通常是为了进行后续的聚集操作。distribute by 子句可以做这件事。类似MR中partition,进行分区,结合sort by使用。Hive要求DISTRIBUTE BY语句要写在SORT BY语句之前。
cluster by:当distribute by和sort by字段相同时,可以使用cluster by方式
3. 分区表和分桶表
①分区表
分区字段不能是表中已经存在的数据,可以将分区字段看作表的伪列。
# 创建单个分区
alter table xxxx add partition(day='20200404');
# 删除单个分区
alter table xxxx drop partition (day='20200406');
# 查看分区表有多少分区
show partitions xxxx;
# 查看分区表结构
desc formatted xxxx;
动态分区
对分区表 Insert 数据时候,数据库自动会根据分区字段的值,将数据插入到相应的分区中;
# 开启动态分区参数设置
hive.exec.dynamic.partition=true
hive.exec.dynamic.partition.mode=nonstrict
hive.exec.max.dynamic.partitions=1000
hive.exec.max.created.files=100000
hive.error.on.empty.partition=false
# 案例实操
create table dept_partition_dy(id int, name string) partitioned by (loc int) row format delimited fields terminated by '\t';
insert into table dept_partition_dy partition(loc) select deptno, dname, loc from dept;
show partitions dept_partition;
② 分桶表
分桶规则:Hive 的分桶采用对分桶字段的值进行哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中;
分区针对的是数据的存储路径;分桶针对的是数据文件。
# 重命名表:
ALTER TABLE table_name RENAME TO new_table_name;
#清除表中数据:
truncate table xxxxxxx;
#行转列
CONCAT(string A/col, string B/col…)
CONCAT_WS(separator, str1, str2,...)
COLLECT_SET(col)
#列转行 explode\split\lateral VIEW
SELECT
movie,category_name
FROM table
lateral VIEW
explode(split(category,",")) table_tmp AS category_name;
数据准备:name,orderdate,cost
(1)查询在 2017 年 4 月份购买过的顾客及总人数
select name,count(*) over ()
from business
where substring(orderdate,1,7) = '2017-04'
group by name;
(2)查询顾客的购买明细及月购买总额
select name,orderdate,cost,sum(cost) over(partition by month(orderdate))
from business;
(3)上述的场景, 将每个顾客的 cost 按照日期进行累加
select name,orderdate,cost,
sum(cost) over() as sample1, --所有行相加
sum(cost) over(partition by name) as sample2, --按 name 分组,组内数据相加
sum(cost) over(partition by name order by orderdate) as sample3,--按 name分组,组内数据累加
sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row ) as sample4 ,
--和 sample3 一样,由起点到当前行的聚合
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING and current row) as sample5,
--当前行和前面一行做聚合
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING AND 1 FOLLOWING ) as sample6,
--当前行和前边一行及后面一行
sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING ) as sample7
--当前行及后面所有行
from business;
(4)查询每个顾客上次的购买时间
select name,orderdate,cost,
lag(orderdate,1,'1900-01-01') over(partition by name order by orderdate ) as time1,
lag(orderdate,2) over (partition by name order by orderdate) as time2
from business;
(5)查询前 20%时间的订单信息
select * from (
select name,orderdate,cost, ntile(5) over(order by orderdate) sorted
from business
) t
where sorted = 1;
RANK() 排序相同时会重复,总数不会变
DENSE_RANK() 排序相同时会重复,总数会减少
ROW_NUMBER() 会根据顺序计算
select name,
subject,
score,
rank() over(partition by subject order by score desc) rp,
dense_rank() over(partition by subject order by score desc) drp,
row_number() over(partition by subject order by score desc) rmp
from score;
unix_timestamp:返回当前或指定时间的时间戳
from_unixtime:将时间戳转为日期格式
select from_unixtime(1603843200);
current_date:当前日期
select current_date;
current_timestamp:当前的日期加时间
select current_timestamp;
to_date:抽取日期部分
select to_date('2020-10-28 12:12:12');
weekofyear:当前时间是一年中的第几周
select weekofyear('2020-10-28 12:12:12');
dayofmonth:当前时间是一个月中的第几天
select dayofmonth('2020-10-28 12:12:12');
months_between: 两个日期间的月份
select months_between('2020-04-01','2020-10-28');
add_months:日期加减月
select add_months('2020-10-28',-3);
datediff:两个日期相差的天数
select datediff('2020-11-04','2020-10-28');
date_add:日期加天数
select date_add('2020-10-28',4);
date_format(): 格式化日期
select date_format('2020-10-28 12:12:12','yyyy/MM/dd HH:mm:ss');
常用取整函数
round: 四舍五入
ceil: 向上取整
floor: 向下取整
常用字符串操作函数
upper: 转大写
lower: 转小写
length: 长度
trim: 前后去空格
lpad: 向左补齐,到指定长度
select lpad('atguigu',9,'g');
rpad: 向右补齐,到指定长度
select rpad('atguigu',9,'g');
regexp_replace:使用正则表达式匹配目标字符串,匹配成功后替换!
SELECT regexp_replace('2020/10/25', '/', '-');