文章目录

  • 一. Hadoop与Sql
  • 二. HDFS 文件存储
  • 三. Hive下载与安装
  • 1.Hive简介
  • 2.hive Sql
  • 3.hive 架构
  • 3.1 MetaStore
  • 3.2 Hive vs RDMBS
  • 3.3 Hive的适用场景
  • 4.hive 部署
  • 4.1下载
  • 4.2解压
  • 4.3添加Hive的bin到环境变量:
  • 4.4 修改配置文件
  • 4.5 Hive基本命令
  • 四. Hive DDL与DML基本操作
  • 1. db <==> HDFS directory
  • 2. table <==> HDFS directory
  • 3.分区表
  • 4.DDL操作
  • 4.1 Create
  • 4.2 Drop
  • 4.3 数据类型与分隔符
  • 4.4 导入数据
  • 4.5 修改表名
  • 4.6 DROP和TRUNCATE的区别
  • 4.7 内部表与外部表
  • 4.8 插入数据
  • 4.9 插入数据到静态分区
  • 4.10 插入数据到动态分区
  • 五. Hive 函数的使用
  • 1.between 800 and 1500 == [800,1500]
  • 2.聚合函数
  • 3. group by 分组
  • 4.join:表与表之间的关联
  • 5.日期 JSON处理
  • 6. Array、Map、Struct 数据类型
  • 7.分组 TOPN
  • 8. explode 函数 (行转列)


一. Hadoop与Sql

Hadoop
	广义
		Hadoop、Hive、Sqoop
		圈内的这些框架:
			Hadoop
			Hive
			HBase
			Sqoop
			Spark
			Flink
			Presto/Impala...
			CDH/HDP
	狭义
	
	
hadoop.apache.org/	
项目名称.apache.org	
	
MR编程:
	麻烦、痛苦 Java
	
SQL:
	Database  Table
	select * from xxx group by y...

SQL on Hadoop

二. HDFS 文件存储

HDFS: 
	mkdir -p hdfspath
	put xxx hdfspath
	
	HDFS上的数据:文本
		id、name、age
	1,pk,30   1\tpk\t30  1 pk 30
	2,J,18
	普通的不能在普通的文本文件 如何使用SQL进行查询呢?
	
	Table:column name/type
		id int
		name string/varchar2...
		age int
		==> Schema  元数据(描述数据的数据)  源数据
	==> SQL
		id  index:0
		name  index:1
		age  index:2
	
	
	文本的路径在哪?
	文本对应的schema?
	文本的分隔符是什么?
	===> 才可以把文件系统上的文件和Table对应起来  Schema
	
	
	元数据:meta   文本文件的描述数据 MySQL
	源数据:raw    HDFS存的文本文件
	
	想使用SQL进行查询Hadoop上的数据
		源数据和元数据都是必不可少的
	
	Hive的数据存放在哪里?HDFS + MySQL
	
批流一体:Spark/Flink
	批:离线
	流:实时
	
	
	
	
data warehouse
	离线/实时
	
reading,  SQL
writing,  结果、中间结果
managing large datasets  大数据集
residing in distributed storage  FS:HDFS、S3...
using SQL ==> 大家喜欢的、简单	
	
A command line tool and 
JDBC driver 
are provided to connect users to Hive

三. Hive下载与安装

1.Hive简介

Facebook  海量结构化的数据统计问题
	构建在Hadoop之上的数据仓库/DW
		Hadoop: HDFS  MR  YARN
	职责:SQL ==> 对应的引擎的作业跑就行 
	其实就是一个客户端而已,Hive并不存在集群的概念
	底层引擎:MR  Tez  Spark
		只要一个参数进行引擎的切换,SQL用法不变的

2.hive Sql

Hive QL(HQL):和我们RDBMS的SQL类似  类SQL
	离线/批计算
		在Hive上一个SQL的执行速度  vs MySQL上的同一个SQL执行速度?
	
	UI有一个文本框,输入SQL,提交按钮

	SQL再简单,只要是需要参与计算(count(1)) 是需要时间的
	复杂的SQL,等?
	离线的作业都是定时调度/手工执行 ==> 把结果写到某个Hive
	UI去拿结果(不参与计算:select xx from t)
	
	支持函数Function:build-in & UDF

3.hive 架构

3.1 MetaStore

***** 需要做HA
	一旦你的Meta挂了
	HDFS源数据的元数据就没有

    Hive的元数据是存放在MySQL  <== MetaStore
    MetaStore是一个通用的组件
	SparkSQL/Flink/Impala/Presto
	Hive里面创建的表 在其他框架也是能访问

3.2 Hive vs RDMBS

共同点:SQL、事务、insert (values)/update/delete、分布式
	不同点:规模、成本、数据体量

3.3 Hive的适用场景

离线、延时性不关注	

   有一个新的框架诞生,SQL写法与普通的SQL语法不同

4.hive 部署

4.1下载

archive.cloudera.com/cdh5/cdh/5/

	在生产上对应的软件版本一定要控制好
	版本选择的基本原则:尾巴一样(版本号): cdh5.16.2
	Hadoop/Hive/Sqoop/HBase/Oozie...
	Spark例外
	所以Hive的版本:hive-1.1.0-cdh5.16.2
	hive-1.1.0-cdh5.16.2-src.tar.gz  源码
	hive-1.1.0-cdh5.16.2.tar.gz  安装包
	wget http://archive.cloudera.com/cdh5/cdh/5/hive-1.1.0-cdh5.16.2.tar.gz

4.2解压

tar -zxvf hive-1.1.0-cdh5.16.2.tar.gz -C ~/app/	
		
	配置文件:
		conf Hive相关的配置文件
		bin  Hive相关的脚本

4.3添加Hive的bin到环境变量:

export HIVE_HOME=/home/hadoop/app/hive-1.1.0-cdh5.16.2
export PATH=$HIVE_HOME/bin:$PATH
注意:改完一定要先source下,或者打开一个新的窗口

4.4 修改配置文件

Hive的元数据是在MySQL里面的
如果要访问MySQL的话,需要如下几个参数
	driver、url、user、password
还需要一个MySQL的驱动类
	***:不建议使用MySQL8的区别
	需要把MySQL的区别拷贝到$HIVE_HOME/lib
	
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://localhost:3306/rzdata_hive?createDatabaseIfNotExist=true</value>
	</property>

	<property>
	  <name>javax.jdo.option.ConnectionDriverName</name>
	  <value>com.mysql.jdbc.Driver</value>
	</property>

	<property>
	  <name>javax.jdo.option.ConnectionUserName</name>
	  <value>root</value>
	</property>

	<property>
	  <name>javax.jdo.option.ConnectionPassword</name>
	  <value>pentaKill</value>
	</property>
</configuration>			
			
Hive相关的配置参数均来自:	
	https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties

	hive-env.sh
		HADOOP_HOME
		export HADOOP_HEAPSIZE=1024

	
特别说明:
	使用Hive时一定要确保Hadoop环境是OK

4.5 Hive基本命令

(1)!clear;

(2)exit;

(3)show databases;

    default   Hive里默认就有一个名字为default的数据库
    default指向的路径是${hive.metastore.warehouse.dir}
    
(4)create database rz_hive;
   
    HDFS上的目录:	
    /user/hive/warehouse/rz_hive.db
		
	规则:${hive.metastore.warehouse.dir}/数据库的名称.db
		
	数据库存放在HDFS的什么位置呢?
		hive.metastore.warehouse.dir
			/user/hive/warehouse
	
	在default数据库下创建一个表
		create table student(id int, name string, age int);
		drop table student;
	表在HDFS上的目录:${数据库的目录}/表名/
	
(5) use 数据库名称    切换到指定的数据库名称对应数据库中去
		create table student2(id int, name string, age int);

	如何在控制台上显示出来当前处于哪个数据库呢?
		hive.cli.print.current.db
	
(6) Hive里面涉及到参数的问题如何设置呢?
		1) hive-site.xml  全局配置
		2) set hive.cli.print.current.db;  局部  对当前session有效
			set key; 显示key的值
			set key=value;
			set hive.cli.print.current.db=true;	
	
	hive.cli.print.current.db
	hive.cli.print.header
	
	调优的时候很多参数是可以调整的
	为什么不配置到全局的里面去呢?
		调优是针对作业的,不一定是针对全局的
	set key=value;  //设置参数
	sql... 
	set key         // 还原参数
	
(7)查看表结构命令:desc formatted student;
	
(8)Hive运行时的日志信息在哪里?
		hive.log.threshold=ALL
		hive.root.logger=WARN,DRFA
		hive.log.dir=${java.io.tmpdir}/${user.name}
		hive.log.file=hive.log
		
		${java.io.tmpdir}: /tmp
		${user.name}     : hadoop
		/tmp/hadoop/hive.log
		
	
    select * from student; 
	是在hive命令行里面执行的
	先要进入hive

(9)交互式命令行:

    直接在linux控制台上执行即可
	hive -e "select * from student"
	hive -f 指定sql文件

(10)shell脚本:

	hive -e "select * from student day=${day}"
	hive -f 指定sql文件

    crontab/调度框架 定时调度
	离线作业执行粒度是一天一次
	每天凌晨3点去统计昨天的数据

四. Hive DDL与DML基本操作

1. db <==> HDFS directory

default  /user/hive/warehouse
rz_hive  /user/hive/warehouse/rz_hive.db

2. table <==> HDFS directory

default  /user/hive/warehouse/student/表的文件内容(可以有多个文件的)
rz_hive  /user/hive/warehouse/rz_hive.db/student/...

3.分区表

Hive: db/table/partition对应的都是HDFS上的文件夹

通过类似于
	【表文件夹/文件】
	【表文件夹/分区文件夹(1..n)/文件】

4.DDL操作

CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[MANAGEDLOCATION hdfs_path]
[WITH DBPROPERTIES (property_name=property_value, ...)];

[]:表示可有可无

==>

4.1 Create

CREATE DATABASE IF NOT EXISTS hive;
CREATE DATABASE IF NOT EXISTS hive2 LOCATION '/hive/directory';

4.2 Drop

DROP DATABASE IF EXISTS hive2 CASCADE; 
生产:创建数据库   修改/删除(级联删除) 几乎是用不上的

One2Many : db2table
2:to

4.3 数据类型与分隔符

数据类型
	数值类型:int/float/double/bigint 
	字符串类型:string
	
	
分隔符
	(*****)log里面字段与字段之间的分隔符是什么
	生产中用的比较多: , \t
	行与行之间的分隔符是什么
	id name age
	1,pk,30
	2,xingxing,60
	
	1	pk	30
	2	xingxing	60
	
	GET www.pentaKill.com
	对于一个表里面,字段与字段的分隔符是固定
	不然的话读取不出来的


CREATE TABLE table_name 
[(col_name data_type [column_constraint_specification] [COMMENT col_comment], ... [constraint_specification])]
[
[ROW FORMAT row_format] 
AS select_statement
 
CREATE TABLE table_name
  LIKE existing_table_or_view_name
  [LOCATION hdfs_path];

row_format
  : DELIMITED [FIELDS TERMINATED BY char [ESCAPED BY char]] [COLLECTION ITEMS TERMINATED BY char]
 
file_format:
  : SEQUENCEFILE
  | TEXTFILE    -- (Default, depending on hive.default.fileformat configuration)
  | RCFILE      -- (Note: Available in Hive 0.6.0 and later)
  | ORC         -- (Note: Available in Hive 0.11.0 and later)
  | PARQUET     -- (Note: Available in Hive 0.13.0 and later)
  | AVRO        -- (Note: Available in Hive 0.14.0 and later)
  | JSONFILE    -- (Note: Available in Hive 4.0.0 and later)
  | INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname
 
column_constraint_specification:
  : [ PRIMARY KEY|UNIQUE|NOT NULL|DEFAULT [default_value]|CHECK  [check_expression] ENABLE|DISABLE NOVALIDATE RELY/NORELY ]
 
default_value:
  : [ LITERAL|CURRENT_USER()|CURRENT_DATE()|CURRENT_TIMESTAMP()|NULL ] 
 
constraint_specification:
  : [, PRIMARY KEY (col_name, ...) DISABLE NOVALIDATE RELY/NORELY ]
    [, PRIMARY KEY (col_name, ...) DISABLE NOVALIDATE RELY/NORELY ]
    [, CONSTRAINT constraint_name FOREIGN KEY (col_name, ...) REFERENCES table_name(col_name, ...) DISABLE NOVALIDATE 
    [, CONSTRAINT constraint_name UNIQUE (col_name, ...) DISABLE NOVALIDATE RELY/NORELY ]
    [, CONSTRAINT constraint_name CHECK [check_expression] ENABLE|DISABLE NOVALIDATE RELY/NORELY ]	
	


create external table pentaKill_emp_external(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double,
deptno int
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
location '/hive/external/emp/'
;

4.4 导入数据

LOAD DATA LOCAL INPATH '/home/hadoop/data/emp.txt' OVERWRITE INTO TABLE pentaKill_emp;

LOCAL: 本地,你执行hive命令那个机器	
无LOCAL:HDFS路径	
	
Hive加载数据在生产上使用:
1) load data
2) insert (不是values)


create table pentaKill_emp2 like pentaKill_emp;
create table pentaKill_emp3 as select * from pentaKill_emp;

4.5 修改表名

ALTER TABLE pentaKill_emp2 RENAME TO pentaKill_emp2_new;

4.6 DROP和TRUNCATE的区别

4.7 内部表与外部表

EXTERNAL:外部表
	元数据被删除
	HDFS数据依然存在
	
MANAGED:内部表
	HDFS的数据被清空
	元数据也会被清空

架构:元数据信息是存放在MySQL

4.8 插入数据

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
LOAD DATA LOCAL INPATH '/home/hadoop/data/emp.txt' INTO TABLE pentaKill_emp;
LOAD DATA INPATH '/test/emp.txt' INTO TABLE pentaKill_emp;

append
Standard syntax:
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1 FROM from_statement;
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement;
 
Hive extension (multiple inserts):
FROM from_statement
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1
[INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]] select_statement2]
[INSERT INTO TABLE tablename2 [PARTITION ...] select_statement2] ...;
FROM from_statement
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1
[INSERT INTO TABLE tablename2 [PARTITION ...] select_statement2]
[INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]] select_statement2] ...;
 
Hive extension (dynamic partition inserts):
INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement;
INSERT INTO TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement;




INSERT OVERWRITE [LOCAL] DIRECTORY directory1
  [ROW FORMAT row_format] [STORED AS file_format] (Note: Only available starting with Hive 0.11.0)
  SELECT ... FROM ...
  
  
INSERT OVERWRITE LOCAL DIRECTORY '/home/hadoop/data/tmp/' select empno,ename from pentaKill_emp;

4.9 插入数据到静态分区

RDBMS 分区
	who when what
	一天一个表
	log_yyyyMMdd
	union
	
	减少全表扫描的可能性
	降低IO

	/user/hive/warehouse/emp/day=20221001/...
	/user/hive/warehouse/emp/day=20221002/...
	Hive的分区其实对应的还是HDFS上的文件夹
	元数据里面肯定也有一张对应的表用来存放分区信息的


[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]

	...表示一张表可以有多个分区字段


create table emp_partition(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double,
deptno int
) 
PARTITIONED BY (day string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
;	


LOAD DATA LOCAL INPATH '/home/hadoop/data/emp.txt' INTO TABLE emp_partition PARTITION(day="20220808");

4.10 插入数据到动态分区

手动创建hdfs的分区文件夹,需要MSCK,hive元数据表才知道; 等价于 add partition方法

MSCK REPAIR TABLE emp_partition [ADD/DROP/SYNC PARTITIONS];



把pentaKill_emp表中deptno=20的数据写到新表里
create table emp2(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double
) 
PARTITIONED BY (deptno int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
;	

LOAD DATA LOCAL INPATH '/home/hadoop/data/emp.txt' INTO TABLE emp_partition_2 PARTITION(day="20220808",hour="21");

动态分区

insert into table emp2 partition(deptno) select empno,ename,job,mgr,hiredate,sal,comm,deptno from pentaKill_emp;

五. Hive 函数的使用

1.between 800 and 1500 == [800,1500]

0.0 和 null 不是一个概念


user_id:  ""  ''  null  
不管是SQL还是代码业务逻辑:一定要考虑全面
	单元测试的重要性
		单元测试不是QA做的,而是RD做的

2.聚合函数

max/min/count/sum/avg

3. group by 分组

求每个部门的平均工资
	按照部门分组
	分组后求每个组的平均工资
select deptno,avg(sal) from pentaKill_emp group by deptno;	

每个部门、每个岗位的最高工资
	部门、岗位进行分组
	分组后求最高工资
	
select deptno,job, max(sal) from pentaKill_emp group by deptno,job;	


求每个部门的平均工资 > 2500
	where 
	having

select deptno,avg(sal) from pentaKill_emp group by deptno having avg(sal)>2500;	

hive.fetch.task.conversion
hive.execution.engine

4.join:表与表之间的关联

select
a.id,a.name,b.age
from
a full join b
on a.id = b.id;

默认的join是inner join
left:以左表为基准,左表的数据都在,匹配不上右表数据的字段为null

inner join = join
left outer join = left join

Hive内置 build-in
	FunctionRegistry

5.日期 JSON处理

时间
数学
字符串: 嵌套


create table hive_topn(
id int, age int, name string, sex string
)row format delimited fields terminated by ',';

拥有兄弟的人以及兄弟的名称

create table t_rate as
select
userid, movie,rate,time,
from_unixtime(cast(time as bigint)) as ts,
year(from_unixtime(cast(time as bigint))) as year,
month(from_unixtime(cast(time as bigint))) as month,
day(from_unixtime(cast(time as bigint))) as day,
hour(from_unixtime(cast(time as bigint))) as hour,
minute(from_unixtime(cast(time as bigint))) as minute
from
(select json_tuple(json,'movie','rate','time','userid') as(movie,rate,time,userid) from rating_json) t

6. Array、Map、Struct 数据类型

<==  定义表结构&查询数据

7.分组 TOPN

分组TopN: 每个性别中年龄最大的2个人  Top2

select
sex,age
from hive_topn
group by sex,age order by age desc

**(分组排序)深入骨髓,随手就来

select id,age,name,sex
from
(
select id,age,name,sex,
row_number() over(partition by sex order by age desc) as rank
from hive_topn
) t where rank<=2;

8. explode 函数 (行转列)

wc

select word,count(1) as cnts
from
(select explode(split(sentence,",")) as word from hive_wc ) t
group by word
order by cnts desc;