关于 Hive 的必知必会

传统数仓无法满足快速增长的海量数据存储需求,无法有效处理不同类型的数据,并且计算和处理能力不足,因此就诞生了HDFS(Hadoop Distributed File System),但是HDFS的使用门槛不够友好,大家熟悉的SQL不能直接跑,因此需要一个框架,使用SQL来做HDFS的查询。Hive正是基于类似SQL的语言完成对hdfs数据的查询分析的框架。

一、Hive的特点

  •  Hive可以查询和管理PB级别的分布式数据
  • 本身不存储和处理数据,可以看成是一种工具
  • 依赖HDFS存储数据
  • 依赖MapReduce(默认)、Tez、Spark等计算引擎
  • HiveQL支持类似普通SQL的查询语言
  • 支持原始类型包括数值型、Boolean,字符串,时间戳,复杂类型包括数组,map,struct

二、Hive同传统数据库的区别

Hive 传统数据库

设计目的

Hive是为数据仓库设计的,主要用于海量数据的存储和分析 传统数据库主要用于业务平台的事务处理,支持高频的数据增删改查操作,通常用于在线应用

数据存储位置

存储在HDFS中,依赖于HDFS进行分布式文件存储 将数据保存在块设备或本地文件系统中

数据更新能力

不支持对数据的改写和添加,所有的数据都是在加载时确定好的 通常需要经常进行数据修改,可以使用INSERT INTO…VALUES添加数据,使用UPDATE…SET修改数据

适用场景

适用于需要进行大规模数据分析的场景,如数据挖掘和报表生成

三、Hive 架构和组件 

  • Metastore是一个中央存储库,存储关于表和分区结构的元数据信息,包括列和列类型信息
  • Metastore通常是一个关系数据库。Hive的元数据可能要面临不断地更新/修改和读取操作,所以它显然不适合使用Hadoop文件系统进行存储,目前Hive将元数据存储在RDBMS中,比如存储在MySQL。 对外提供了一个Thrift接口,用于查询和操作Hive元数据。

 四、分区 & 分桶

一句话,分区分桶是为了提高Hive的查询效率。

4.1 分区

基于分区键把具有相同分区键的数据存储在一个目录下,在查询某一个分区的数据的时候,只需要查询相对应目录下的数据,而不会执行全表扫描。

如上图所示,假如你有一个存储学生信息的表,表名为 student_details,列分别是 student_id,name,department,year 等。现在,如果你想基于 department 列对数据进行分区。那么属于同一个 department 的学生将会被分在同一个分区里面。

在物理上,一个分区其实就是表目录下的一个子目录。

假如在 student_details 表里面有三个 department 的数据,分别为 EEE,ECE 和 ME。那么这个表总共就会有三个分区,也就是图中的绿色方块部分。对于每个 department ,您将拥有与该 department 相关的所有数据,这些数据位于表目录下的单独子目录中。

如果 department = EEE 的学生数据被存储在/user/hive/warehouse/student_details/department=EEE 目录下。那么查询 department 为 EEE 的学生信息,只需要查询 EEE 目录下的数据即可,不需要全表扫描,这样查询的效率就比较高。而在真实生产环境中,你需要处理的数据可能会有几百 TB,如果不分区,在你只需要表的其中一小部分数据的时候,你不得不走全表扫描,这样的查询将会非常慢而且浪费资源。

Hive动态分区与静态分区的区别及使用场景

静态分区:在插入数据时,用户手动指定分区的值

动态分区:在插入数据时,分区的值由数据本身决定,用户不需要手动指定

在静态分区中,用户在插入数据时,需要明确指定分区的值。这意味着每个插入操作都需要提供一个具体的分区路径。例如,当将数据插入到某个按“日期”分区的表中时,用户需要明确指定“日期”的值。假设我们有一个销售记录表,按“日期”进行静态分区。插入数据的SQL语句如下:

INSERT INTO sales PARTITION (date='2023-10-01')
SELECT * FROM temp_sales WHERE sale_date = '2023-10-01';

在动态分区中,用户在插入数据时,不需要手动指定分区的值。Hive会根据插入数据中的某一列的值自动创建对应的分区。用户只需在INSERT语句中指定分区列,而不必指定具体的值:

INSERT INTO sales PARTITION (date)
SELECT sale_id, product_id, amount, sale_date FROM temp_sales;

静态分区的使用场景

  1. 数据量小且变化不频繁
  2. 分区数量已知且稳定
  3. 开发和测试环境
动态分区的使用场景
  1. 数据量大且频繁变化(如在线交易系统,数据量大且每天的数据插入量不确定)
  2. 复杂的分区需求
  3. 实时数据处理

4.2 分桶

Hive 可以对每一个表或者是分区,进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive 是针对表的某一列进行分桶。Hive 采用对列值进行哈希计算,然后除以桶的个数求余的方式决定该条记录存放在哪个桶中。分桶的好处是可以获得更高的查询处理效率。使取样更高效。

每个桶只是表目录或者分区目录下的一个文件,如果表不是分区表,那么桶文件会存储在表目录下,如果表是分区表,那么桶文件会存储在分区目录下。所以你可以选择把分区分成 n 个桶,那么每个分区目录下就会有 n 个文件。

创建分区表语法:

CREATE TABLE table_name (column1 data_type, column2 data_type)
PARTITIONED BY (partition1 data_type, partition2 data_type,….);

分桶表创建命令:

CREATE TABLE table_name
PARTITIONED BY (partition1 data_type, partition2 data_type,….) 
CLUSTERED BY (column_name1, column_name2, …) 
SORTED BY (column_name [ASC|DESC], …)] 
INTO num_buckets BUCKETS;

五、Hive 文件格式与压缩格式

存储格式行存储和列存储
  1. 行存储可以理解为一条记录存储一行,通过条件能够查询一整行数据。
  2. 列存储,以字段聚集存储,可以理解为相同的字段存储在一起。

5.1 存储格式

存储格式即是指表的数据是如何在HDFS上组织排列的。Hive中常用的存储格式有TEXTFILE 、SEQUENCEFILE、AVRO、RCFILE、ORCFILE、PARQUET等。主要在加载速度、压缩率、查询速度、存储方式等方面有一些差异。

TEXTFILE

  • 数据表的默认格式,存储方式:行存储。
  • 加载速度最快
  • 可以使用Gzip压缩算法,但压缩后的文件不支持split(可能造成Map端的数据倾斜)。
  • 在反序列化过程中,必须逐个字符判断是不是分隔符和行结束符,因此反序列化开销会比SequenceFile高几十倍。

SEQUENCEFILE

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沙滩de流沙

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值