大数据之路系列之hive(05)

大数据之路系列之hive(05)



一、什么是Hive?

Hive中包含的有SQL解析引擎,它会将SQL语句转译成M/R Job,然后在Hadoop中执行

二、Hive的数据存储

Hive的数据存储基于Hadoop的 HDFS
Hive没有专门的数据存储格式
Hive默认可以直接加载文本文件(TextFile),还支持SequenceFile、RCFile等文件格式
针对普通文本数据,我们在创建表时,只需要指定数据的列分隔符与行分隔符,Hive即解析里面的数据

三、Hive的系统架构

在这里插入图片描述

  • 用户接口,包括 CLI、JDBC/ODBC、WebGUI
    CLI,即Shell命令行,表示我们可以通过shell命令行操作Hive
    JDBC/ODBC 是 Hive 的Java操作方式,与使用传统数据库JDBC的方式类似
    WebUI是通过浏览器访问 Hive
  • 元数据存储(Metastore),注意:这里的存储是名词,Metastore表示是一个存储系统
    Hive中的元数据包括表的相关信息,Hive会将这些元数据存储在Metastore中,目前Metastore只支持 mysql、derby。
  • Driver:包含:编译器、优化器、执行器
    编译器、优化器、执行器可以完成 Hive的 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划最终存储在 HDFS 中,并在随后由 MapReduce 调用执行
  • Hadoop:Hive会使用 HDFS 进行存储,利用 MapReduce 进行计算
    Hive 的数据存储在 HDFS 中,大部分的查询由 MapReduce 完成(特例 select * from table 不会生成 MapRedcue 任务,如果在SQL语句后面再增加where过滤条件就会生成MapReduce任务了。
    从hive2开始官方就不建议使用MapReduce作为数据引擎了,但是截至到hive3默认的数据引擎依然是MapReduce,只是建议数据引擎更换成spark或者是flink

四、Metastore

Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在的hdfs目录等
Metastore默认使用内嵌的derby数据库,Derby数据库的缺点:在同一个目录下一次只能打开一个会话
不建议使用默认的Derby推荐使用MySQL作为外置存储引擎,可以支持多用户同时访问以及元数据共享。

五、Hive VS Mysql

				HIVE						MySQL
数据存储位置		HDFS						本地磁盘
数据格式			用户定义						系统决定
数据更新			不支持(不支持修改和删除)		支持(支持增删改查)
索引				有,但较弱,一般很少用			有,经常使用的
执行				MapReduce					Executor
执行延迟			高							低
可扩展性			高							低
数据规模			大							小

六、数据库 VS 数据仓库

数据库:传统的关系型数据库(MySQL、Oracle)主要应用在基本的事务处理,数据库支持增删改查这些常见的操作,属于OLTP。
数据仓库:主要做一些复杂的分析操作,侧重决策支持,相对数据库而言,数据仓库分析的数据规模要大得多。但是数据仓库只支持查询操作,不支持修改和删除,属于OLAP。

七、OLTP VS OLAP

OLTP(On-Line Transaction Processing):操作型处理,称为联机事务处理,也可以称为面向交易的处理系统,它是针对具体业务在数据库联机的日常操作,通常对少数记录进行查询、修改。用户较为关心操作的响应时间、数据的安全性、完整性等问题

OLAP(On-Line Analytical Processing):分析型处理,称为联机分析处理,一般针对某些主题历史数据进行分析,支持管理决策。

八、hive的安装

九、hive的使用

启动命令
nohup hive --service metastore >> /export/servers/hive/log/metastore.log 2>&1 &
nohup hive --service hiveserver2 >> /export/servers/hive/log/hiveserver2.log 2>&1 &
bin/beeline -u jdbc:hive2://localhost:10000

十、Hive中数据库的操作

默认的存储位置是 /user/hive/warehouse

十一、Hive指定列和行的分隔符

默认的列分隔符是\001
默认的行的分隔符是\n

#指定分隔符
create external table stu
(
    stu_id       int,
    stu_name     string,
    stu_birthday date,
    online       boolean
)row format delimited
    fields terminated by  '\t'
    lines terminated by '\n'
;

十二、Hive的数据类型

  • 一类是基本数据类型
数据类型		开始支持版本
TINYINT			~			
SMALLINT		~			
INT/INTEGER		~			
BIGINT			~			
FLOAT			~			
DOUBLE			~			
DECIMAL		0.11.0		
TIMESTAMP	0.8.0
DATE		0.12.0
STRING		 	~
VARCHAR		0.12.0
CHAR		0.13.0
BOOLEAN			~
  • 一类是复合数据类型
数据类型		开始支持版本		格式
ARRAY		0.14.0			ARRAY<data_type>
MAP			0.14.0			MAP<primitive_type, data_type>
STRUCT		~				STRUCT<col_name : data_type, ...>

1.array

适合场景:数组结构,适合存储不固定个数的字段。
创建array字段

#创建array字段的表
create table  stu4(
     stu_id       int,
    stu_name     string,
    stu_favors  array<string>
) row format delimited
    fields terminated by  '\t'
    #collection 要放在中间,放fields前面会报错
    collection items terminated by ','
    lines terminated by '\n';
#加载数据到测试表中
load data inpath '/test4/stu3.txt' into table test_db.stu4;
#使用角标的形式获取数据 角标从0开始
select stu_id,stu_favors[1] from test_db.stu4;

2.map

适合场景:某个字段包含多个key-value的键值对形式

#创建mapy字段的表
create table  stu6(
     stu_id       int,
    stu_name     string,
    stu_scores  map<string,int>
) row format delimited
    fields terminated by  '\t'
    #需要加两行,字段分割已经mapkey-value的分隔
    collection items terminated by ','
    map keys terminated by ':'
    lines terminated by '\n';
 #导入数据
load data inpath '/test4/stu6.txt' into table test_db.stu6;
#通过key进行查询
select stu_id,stu_scores['chinese'] from test_db.stu6;

3.struct

适合场景:储存一个对象数据

#创建structy字段的表
create table  stu7(
     stu_id       int,
    stu_name     string,
    stu_favors  struct<first_favor:string,second_favor:string,three_favor:string>
) row format delimited
    fields terminated by  '\t'
    collection items terminated by ','
    map keys terminated by ':'
    lines terminated by '\n';

load data inpath '/test4/stu3.txt' into table test_db.stu7;
#使用.属性的形式获取
select stu_id,stu_favors.three_favor from test_db.stu7;

4.map和struct的区别

Struct和Map的区别
如果从建表语句上来分析,其实这个Struct和Map还是有一些相似之处的
来总结一下:

map中可以随意增加k-v对的个数
struct中的k-v个数是固定的

map在建表语句中需要指定k-v的类型
struct在建表语句中需要指定好所有的属性名称和类型

map中通过[]取值
struct中通过.取值,类似java中的对象属性引用

map的源数据中需要带有k-v
struct的源数据中只需要有v即可

总体而言还是map比较灵活,但是会额外占用磁盘空间,因为他比struct多存储了数据的key
struct只需要存储value,比较节省空间,但是灵活性有限,后期无法动态增加k-v

十三、Hive中的表类型

内部表、外部表、分区表、桶表

1.内部表

默认的表类型,实际存储在warehouse目录下;
load加载数据的时候数据会移动到warehouse目录下;
删除数据的时候数据也会删除
一般不用这个类型的表

2.外部表

建表语句中包含external;

#建表语句
create external table student2
(
    stu_id       int,
    stu_name     string,
    favors  array<string>,
    scores map<String,int>,
    address struct<home_addr:string,office_addr:string>
)
    row format delimited
    fields terminated by  '\t'
    collection items terminated by ','
    map keys terminated by ':'
    lines terminated by '\n'  location '/test4/external'
;

外部表删除不会将数据同时删除;
外部表可以直接读取它location下的文件内容无须load 打他 input加载;
日常更多的是先有数据进入到hdfs,然后根据目录创建hive表,不需要进行加载数据自动进入,同时删除不影响数据
几乎都是使用外部表

3.分区表

使用partitioned by指定区分字段
通过类型进行分区,查询的时候可以避免全表扫描;
创建表: partitioned by (dt string) location ‘/test4/external/partition’
数据落地:/test4/external/partition/dt=2022-01-03
加载分区数据: alter table partition_1 add partition (dt=‘2020-01-02’);
数据落地目录的时候规划好目录,建立外部分区表只需要加载分区即可载入数据
几乎都是使用外部表分区

4.分桶表

桶表是对数据进行哈希取值,然后放到不同文件中存储

create table bucket_tb(
id int
) clustered by (id) into 4 buckets;

加载数据只能使用其他表的数据进行加载
insert into table … select … from …;
查询分桶的数据 select * from bucket_tb tablesample(bucket 1 out of 4 on id);
优势:1.适合抽样 2.适合join 两个分桶表相同的ID会分到同一桶中,所以效率会高
缺点:只能使用insert的形式新增
使用少

十四、Hive高级函数应用

1.行转列

COLLECT_SET() 、COLLECT_LIST() 可以将多行数据合并成一行数组,set是去重后的
CONCAT_WS() 可以将数据进行切分

2.列转行

SPLIT()、EXPLODE()和LATERAL VIEW
split切分成数组 EXPLODE可以将数组转成多行 LATERAL VIEW 如果需要加入其它字段需要使用到这个
select name,favor_new from student_favors_2 lateral view explode(split(favorlist, ‘,’)) table1 as favor_new ;

十四、Hive排序相关函数

1.ORDER BY

全局排序

2.SORT BY

set mapreduce.job.reduces = 2;
reduce端进行排序,局部有序

3.DISTRIBUTE BY

分区排序,结合sort by 使用;类似通过名称分区然后分数排序

4.CLUSTER BY

cluster by id 等于 distribute by id sort by id 但是只能升序

十五、数据倾斜处理

#可以对明确知道数据量大的值打散后再进行处理
select owner_id,sum(cut) from (
    select owner_id, count(1) cut
from ods_zjzb_object_h3d5 group by  owner_id,case when owner_id='617256440bbe2f7f1ee00f61' then hash(rand())%5 else 0 end
              ) a  group by owner_id;


十六、数据压缩格式

默认的格式是textfile格式。
这种格式的数据在存储层面占用的空间比较大,影响存储能力,也影响计算效率

1.mapreduce中常见的压缩格式

DEFLATE 底层是zlib
Gzip DEFLATE的封装
Bzip2
Lz4
Lzo
Snappy
在这里插入图片描述
是否可以切分:针对textfile文件来说,如果是否,无论文件多大只能是一个map任务进行处理。对于特殊的文件格式,还是可以实现切分的;这是文件自身决定的,和压缩格式没有关系。非常重要
压缩比:压缩比越高,文件越小
总结 Snappy综合的性能比较高,应用广。

2.数据存储格式

在这里插入图片描述
工作中使用最多是TextFile、ORC和Parquet
默认情况下使用TextFile即可,想要提高数据存储和计算效率,可以考虑使用ORC或者Parquet。

3.数据存储格式之ORC

建表语句
create external table stu_orc_snappy_compress(
id int,
name string,
city string
)row format delimited
fields terminated by ‘,’
lines terminated by ‘\n’
stored as orc
location ‘hdfs://bigdata01:9000/stu_orc_snappy_compress’
tblproperties(“orc.compress”=“SNAPPY”);

在创建ORC数据存储格式表的时候,所有关于ORC的参数都在建表语句中的tblproperties中指定,不需要在hive的命令行中使用set命令指定了。
ORC支持的参数主要包括这些:
在这里插入图片描述

4.数据存储格式之PARQUET

在这里插入图片描述
create external table stu_parquet_snappy_compress(
id int,
name string,
city string
)row format delimited
fields terminated by ‘,’
lines terminated by ‘\n’
stored as parquet
location ‘hdfs://bigdata01:9000/stu_parquet_snappy_compress’
tblproperties(“parquet.compression”=“snappy”);

5.数据存储格式总结

所以最终建议,在工作中选择ORC+Snappy。

但是有时候在选择数据存储格式的时候还需要考虑它的兼容度,是否支持多种计算引擎。

假设我希望这一份数据,既可以在Hive中使用,还希望在Impala中使用,这个时候就需要重点考虑这个数据格式是否能满足多平台同时使用。

Impala很早就开始支持Parquet数据格式了,但是不支持ORC数据格式,不过从Impala 3.x版本开始也支持ORC了。
如果你们使用的是Impala2.x版本,还想要支持Hive和Impala查询同一份数据,这个时候就需要选择Parquet了。

相对来说,Parquet存储格式在大数据生态圈中的兼容度是最高的。

Parquet官网上有一句话,说的是Parquet可以应用于Hadoop生态圈中的任何项目中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

居高声自远,非是藉秋风

千山万水总是情,赏个一块行不行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值