【大数据】Hive 分区和分桶的区别及示例讲解

一、概述

在大数据处理进程中,Hive是一种十分常用的数据仓库东西。Hive分区和分桶是优化Hive功能的两种方法,它们的差异如下:

【大数据】Hive 分区和分桶的区别及示例讲解

1)分区概述

Hive分区是把数据依照某个特点分红不同的数据子集。

  • 在Hive中,数据被存储在HDFS中,每个分区实践上对应HDFS下的一个文件夹,这个文件夹中保存了这个分区的数据。

  • 因此,在Hive中运用分区,实践上是将数据依照某个特点值进行区分,然后将相同特点值的数据存储在同一个文件夹中。Hive分区的功率提升首要是由于,当进行查询操作时,只需读取与查询相关的数据分区,避免了全表扫描,节约了查询时间

Hive分区的首要作用是:

  • 进步查询功率: 运用分区对数据进行拜访时,体系只需求读取和此次查询相关的分区,避免了全表扫描,然后明显进步查询功率。

  • 降低存储成本: 分区能够愈加方便的删去过期数据,削减不必要的存储。

2)分桶概述

Hive分桶是将数据区分为若干个存储文件,并规则存储文件的数量。

  • Hive分桶的完成原理是将数据依照某个字段值分红若干桶,并将相同字段值的数据放到同一个桶中。在存储数据时,桶内的数据会被写入到对应数量的文件中,最终构成多个文件。

  • Hive分桶首要是为了进步散布式查询的功率。它能够经过将数据区分为若干数据块来将很多数据分发到多个节点,使得数据均衡散布到多个机器上处理。这样分发到不同节点的数据能够在本地进行处理,避免了数据的传输和网络带宽的浪费,一起进步了查询功率。

分桶的首要作用是:

  • 数据聚合: 分桶能够使得数据被分红较小的存储单元,进步了数据核算和聚合的功率。

  • 均衡负载: 数据经过火桶后更简单完成均衡负载,数据能够分发到多个节点中,进步了查询功率。

综上所述,分区和分桶的差异在于其供给的功能优化方向不同。分区适用于关于数据常常进行的聚合查询数据剖析,而分桶适用于关于数据的均衡负载、高效聚合等方面的功能优化。当数据量较大、查询功率比较低时,运用分区和分桶能够有用优化功能。分区首要重视数据的分区和存储,而分桶则重点考虑数据的散布以及查询功率。

【大数据】Hive 分区和分桶的区别及示例讲解

二、环境预备

假如已经有了环境了,能够疏忽,假如想快速布置环境能够参考我这篇文章:经过 docker-compose 快速布置 Hive 详细教程

三、外部表和办理表

在Hive中,能够创立两种类型的表:外部表和办理表。它们之间的首要差异如下:

1)外部表

1、外部表介绍

外部表是指在Hive中创立的表,实践上其数据是存储在外部文件体系(HDFS或本地文件体系)中的。

  • 外部分区表是一种特别类型的表,它们的数据存储在Hive之外的文件体系上,例如HDFS、S3等。
  • 关于外部分区表,Hive只会办理它们的元数据信息,而不会办理数据文件本身,这意味着,假如你运用Hive命令删去一个外部分区表,只会删去该表的元数据,而不会删去数据文件
  • 外部分区表一般用于存储和办理原始数据,这些数据一般需求在多个体系和东西之间共享。

2、示例解说

【示例一】下面是创立Hive外部表的一个示例(数据存储在HDFS):

假定咱们有一个存储在 HDFS 上的数据文件,其途径为'/user/hive/external_table/data',咱们能够经过以下句子,在Hive中创立一个外部表:

# 登录容器
docker exec -it hive-hiveserver2 
# 登录hive客户端
beeline -u jdbc:hive2://hive-hiveserver2:10000  -n hadoop
# 建表
CREATE EXTERNAL TABLE external_table1 (
    column1 STRING,
    column2 INT,
    column3 DOUBLE
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
STORED AS TEXTFILE
LOCATION '/user/hive/external_table/data';

在该表中,咱们指定了表的各列的数据类型和分隔符等信息,而且运用了LOCATION 关键字来指定数据文件的存储位置。这样,在Hive中对该外部表进行查询操作时,Hive会主动去对应的位置读取数据文件,并据此返回查询成果。

load 数据

# 模仿一些数据
cat >data<<EOF
c1,12,56.33
c2,14,58.99
c3,15,66.34
c4,16,76.78
EOF
# 登录hive客户端
beeline -u jdbc:hive2://hive-hiveserver2:10000  -n hadoop
# 加载数据,local 是加载本机文件数据
load data local inpath './data' into table external_table1;

【大数据】Hive 分区和分桶的区别及示例讲解

需求留意的是,在运用外部表时,咱们有必要保证Hive对数据文件的拜访权限与HDFS的文件权限相同,否则会导致外部表的查询失败。此外,在运用外部表时,务必不要删去外部表的数据文件,否则将会导致查询成果的不准确。

【示例一】下面是创立外部表拜访本地数据文件的示例(数据存储在本地,很少运用):

在Hive中,咱们相同能够创立外部表来拜访本地文件体系上的数据文件。在这种情况下,咱们需求留意的是,在Hive的装备中,有必要开启hive.stats.autogather 功能。否则,在查询外部表时或许会呈现过错。

假定咱们有一个存储在本地文件体系上的数据文件,途径为'/path/to/local/file',咱们能够经过以下句子,在Hive中创立一个外部表:

CREATE EXTERNAL TABLE external_table2 (
    column1 STRING,
    column2 INT,
    column3 DOUBLE
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
STORED AS TEXTFILE
LOCATION 'file:///path/to/local/file';
### hive文件存储格局包括以下几类(STORED AS TEXTFILE):
#1、TEXTFILE
#2、SEQUENCEFILE
#3、RCFILE
#4、ORCFILE(0.11今后呈现)
#其中TEXTFILE为默许格局,建表时不指定默许为这个格局,导入数据时会直接把数据文件拷贝到hdfs上不进行处理;

需求留意的是,咱们在运用LOCATION关键字时,要指定为'file:///path/to/local/file',而不是 ‘/path/to/local/file’ ,这是由于咱们需求运用文件体系的URL来拜访本地文件体系上的数据文件。

2)办理表(内部表)

1、办理表(内部表)介绍

办理表是运用Hive自身的存储能力来对数据进行存储和办理的表。在Hive中创立办理表时,有必要指定数据的存储途径。

  • 办理表也称为内部表(Internal Table),办理表是Hive默许创立的表类型,它的数据存储在Hive默许的文件体系上(一般是HDFS)。

  • Hive会主动办理这些表的数据和元数据,包括表的位置、数据格局等。假如你运用Hive命令删去了一个办理表,那么该表的数据也会被删去

  • 一般情况下,办理表用于存储和办理中间成果、汇总数据和根底数据。当数据规模较小时,办理表是一个不错的挑选,由于它能够供给更好的查询功能,一起也更简单办理。

2、示例解说

在Hive中,除了外部表,咱们还能够创立内部表来存储数据。与外部表不同的是,内部表存储的数据位于Hive自身办理的HDFS上,因此,在创立内部表时,咱们需求确保数据能够被正确地上传到HDFS上。下面是创立内部表并存储在本机的示例:

假定咱们有以下数据文件,名为data.csv,存储在本地文件体系的/path/to/local目录下:

cat >data.csv<<EOF
value1,1,2.3
value2,2,3.4
value3,3,4.5
EOF

咱们能够运用以下句子,在Hive中创立一个内部表:

CREATE TABLE internal_table (
    column1 STRING,
    column2 INT,
    column3 DOUBLE
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
# 加载本地数据,LOCAL 
LOAD DATA LOCAL INPATH './data.csv' INTO TABLE internal_table;
# 加载HDFS数据
# 先将文件推送到HDFS上
hdfs dfs -put ./data.csv /tmp/
# 登录hive客户端
beeline -u jdbc:hive2://hive-hiveserver2:10000  -n hadoop
# 加载HDFS上的数据
LOAD DATA INPATH '/tmp/data.csv' INTO TABLE internal_table;
# 查询
select * from internal_table;

【大数据】Hive 分区和分桶的区别及示例讲解
总归,外部表和办理表都能够在Hive中完成数据的存储和办理,但它们之间的不同首要体现在数据的存储和处理方法上。

四、分区表之静态分区和动态分区

Hive中的分区表能够进一步细分为静态分区和动态分区。

静态分区是指经过手动指定分区列的值来创立分区。例如,在创立一个依据年份的分区表时,咱们能够手动指定每个分区名对应的年份:

CREATE TABLE sales (
  id int,
  date string,
  amount double
)
PARTITIONED BY (year string);
ALTER TABLE sales ADD PARTITION (year='2019') location '/data/sales/2022';
ALTER TABLE sales ADD PARTITION (year='2020') location '/data/sales/2023';

在上述示例中,咱们经过 ALTER TABLE 句子手动增加了2019和2020两个年份的分区。

动态分区是指在加载数据时经过SQL句子主动创立分区。例如,在从一个包括出售记录的数据文件中加载数据时,能够主动依据数据中的年份信息创立相应的分区:

INSERT INTO TABLE sales PARTITION (year)
SELECT id, date, amount, YEAR(date)
FROM raw_sales;

在上述示例中,咱们运用 PARTITION 子句指定在 CREATE TABLE 句子中定义的分区列year,并运用 YEAR(date) 表达式从数据中提取出年份信息。

动态分区的长处在于它能够大大简化创立和办理分区表的进程并进步功率;可是需求留意的是,它或许会在某些情况下产生不行预期的行为,例如或许创立太多分区。

总归,静态分区和动态分区都是用于在Hive中办理大型数据集的有用东西,详细运用需求依据详细情况挑选最适合的方法,并了解它们的长处和缺陷。

五、hive分区表严厉形式和非严厉形式

Hive分区表的严厉形式和非严厉形式能够经过以下两个参数进行设置:

  1. hive.exec.dynamic.partition.mode:该参数用于设置分区形式,其默许值strict,即严厉形式。能够将其设置为nonstrict,即非严厉形式
# 登录hive客户端
beeline -u jdbc:hive2://hive-hiveserver2:10000  -n hadoop
# 设置
SET hive.exec.dynamic.partition.mode=nonstrict;
  1. hive.exec.max.dynamic.partitions:该参数用于限制动态分区的最大数量。在非严厉形式下,当动态分区的数量超越该参数指定的值时,Hive将抛出反常。能够经过以下句子来修正该参数:
SET hive.exec.max.dynamic.partitions=<value>;

其中,<value> 为一个整数值,表明限制的动态分区数量。假如需求撤销该限制,能够将该参数设置为一个非正数,例如:

SET hive.exec.max.dynamic.partitions=-1;

需求留意的是,这些参数的设置仅对当前会话有用,也能够将其增加到Hive的装备文件中以在每个会话中主动应用。

总归,hive.exec.dynamic.partition.modehive.exec.max.dynamic.partitions 是操控Hive分区表严厉形式和非严厉形式的两个重要参数,开发人员能够依据自己的需求进行设置。

1)严厉形式

严厉形式要求在加载数据时有必要指定一切分区列的值,否则将会导致抛出反常。例如,鄙人面的分区表中:

CREATE TABLE sales (
  id int,
  date string,
  amount double
)
PARTITIONED BY (year string, month string, day string)
CLUSTERED BY (id) INTO 10 BUCKETS;

在严厉形式下,咱们有必要为year、month和day三个分区列的一切或许取值指定一个分区:

INSERT INTO TABLE sales PARTITION (year='2019', month='01', day='03')
SELECT id, date, amount
FROM raw_sales
WHERE YEAR(date) = 2019 AND MONTH(date) = 1 AND DAY(date) = 3;

在上述示例中,咱们运用 PARTITION 子句手动为分区列year、month、day指定取值。

2)非严厉形式

非严厉形式则允许疏忽某些分区列的值,这样运用 INSERT INTO 句子时只需指定供给的分区值即可。例如:

#
SET hive.exec.dynamic.partition.mode=nonstrict;
INSERT INTO TABLE sales PARTITION (year, month, day)
SELECT id, YEAR(date), MONTH(date), DAY(date), amount
FROM raw_sales
WHERE YEAR(date) = 2019;

在上述示例中,咱们运用 SET 句子设置分区形式为非严厉形式,然后只供给了year分区列的值,而month和day分区列的值是从数据中动态核算得出的。

运用非严厉形式能够简化分区表的创立和办理,但需求留意,它或许会产生一些意料之外的成果(例如或许创立太多分区),所以需求谨慎运用。

总归,分区表的严厉形式和非严厉形式都具有一些长处和缺陷,详细运用需求依据详细情况挑选最适合的方法。

六、分区表和分桶表明例解说

1)分区表明例解说

在Hive中,咱们能够运用分区表来更有用地安排和办理数据。分区表将数据分为子集,每个子集对应一个或多个分区。这样,咱们就能够更快地拜访和查询数据,而不必扫描整个数据集。

创立分区表的语法类似于创立普通表,只不过要运用 PARTITIONED BY 子句指定一个或多个分区列,例如:

# 内部表
CREATE TABLE partitioned_internal_table (
  id INT,
  mesg STRING
)
PARTITIONED BY (
  year INT,
  month INT
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
# 外部表
CREATE EXTERNAL TABLE partitioned_external_table (
  id INT,
  mesg STRING
)
PARTITIONED BY (
  year INT,
  month INT
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
STORED AS TEXTFILE
LOCATION '/user/hive/partitioned_table/data';

上述句子创立了一个分区表,在列column1和column2的根底上,依照year和month两列进行了分区。

【留意】分区的完成依赖于Hive的底层存储Hadoop散布式文件体系(HDFS)。为了确定如何分配数据,Hive要求每个分区对应一个目录,该目录包括该分区数据的一切文件。因此,在将数据加载到分区表中时,有必要供给与分区对应的目录

例如,假如咱们要将一个CSV文件加载到分区表中,咱们能够运用以下句子:

LOAD DATA LOCAL INPATH './file.csv' INTO TABLE partitioned_external_table PARTITION (year=2019, month=1);
# 查看分区
show partitions partitioned_external_table;

在上述句子中,咱们运用 LOAD DATA 子句将 /data/file.csv 文件加载到partitioned_table 表中,并指定了分区year为2019,分区month为1。

假定咱们的CSV文件具有以下内容:

1,test1,2019,1
1,test2,2019,1
2,test3,2022,1
3,test4,2023,1

运用以下句子查询分区表:

SELECT * FROM partitioned_external_table WHERE year=2019 AND month=1;

分区表的长处在于能够更高效地安排数据,一起也允许咱们依据需求删去或增加分区。例如,咱们能够运用以下句子删去分区:

ALTER TABLE partitioned_table DROP PARTITION (year=2019, month=1);

能够运用以下句子增加分区:

ALTER TABLE partitioned_external_table ADD PARTITION (year=2020, month=2);
# 查看分区
show partitions partitioned_external_table;

总归,分区表是办理和查询大型数据集的有用方法,能够协助咱们更轻松地处理很多数据。

2)分桶表明例解说

除了分区表之外,Hive还供给了另一种将数据分割成可办理单元的方法,即分桶。

分区和分桶的概念有一些相似之处,但也存在一些重要的差异。

  • 分区是指依据表的某些列将数据分割成不同的存储单元;
  • 而分桶是指将数据依据哈希函数分红一组固定的桶。

类比于分区,在创立一个分桶表时,咱们需求指定分桶的数量和分桶的列。例如,以下是一个创立分桶表的示例:

CREATE TABLE bucketed_table (
  column1 data_type,
  column2 data_type,
  ...
) 
CLUSTERED BY (column1) -- 分桶列
INTO 10 BUCKETS; -- 桶数量

在上述示例中,咱们将column1作为分桶列,并将数据分红10个桶。

加载数据时,Hive依据指定的桶列核算哈希值,并将数据存储在对应的桶中。

INSERT INTO TABLE bucketed_table VALUES ('value1', 1, 2.3)

查询时,能够运用以下格局指定桶列:

SELECT * FROM bucketed_table TABLESAMPLE(BUCKET x OUT OF y ON column1);

在上述示例中,咱们运用用于抽样数据的 TABLESAMPLE 子句,指定从桶x中抽取数据,并在分桶列column1上进行抽样。

分桶表的长处在于,咱们能够更简单地履行等值和规模查询,并更好地运用MapReduce 的数据本地性,然后进步查询功能。但分桶表也有一些缺陷,例如增加和删去数据触及从头核算哈希函数和移动数据的成本。

总归,分区表和分桶表都是Hive办理和处理大型数据集的重要东西,能够协助咱们更轻松地安排、查询和剖析很多数据。在详细运用时,需求考虑表的存储和查询需求,挑选最适合的表类型。在实践场景中分区用的居多。

关于Hive 分区和分桶的差异和示例解说就先到这里了,有任何疑问欢迎给我留言,后续会继续更新相关文章,请小伙伴耐性等待,也可重视我的公众号【大数据与云原生技能分享】加群交流或私信沟通~。

【大数据】Hive 分区和分桶的区别及示例讲解