我知道这两个操作都是在表中的一列上执行的,但是每个操作有何不同呢。
wwtsj6pe1#
我想我回答这个问题已经晚了,但我的反馈中一直提到这个问题。navneet提供了极好的答案。添加到它的视觉效果。分区有助于消除数据,如果在where子句中使用,where-as-bucketing有助于将每个分区中的数据组织成多个文件,因此同一组数据总是写入同一个bucket。有助于很多列的连接。假设您有一个包含五列的表:name、server\u date、some\u col3、some\u col4和some\u col5。假设您在server\ date上对表进行了分区,并在name列上添加了10个bucket,您的文件结构如下所示。服务器\日期=xyz00000_000001_000002_0........00010_0这里server_date=xyz是分区,000个文件是每个分区中的存储桶。bucket是基于一些散列函数计算的,所以name=sandy的行总是放在同一个bucket中。
92vpleto2#
不同之处在于bucketing按列名划分文件,分区按表中的特定值划分下的文件希望我的定义是正确的
jq6vz3qz3#
配置单元分区:分区根据表列的值将大量数据划分为多个片。假设您存储的是分布在196多个国家的全世界人民的信息,这些国家大约有5亿条条目。如果你想查询来自某个国家(梵蒂冈城)的人,在没有分区的情况下,你必须扫描所有的50亿条条目,甚至要获取一个国家的数千条条目。如果您基于国家对表进行分区,您可以通过只检查一个国家分区的数据来微调查询过程。配置单元分区为列值创建单独的目录。赞成的意见:水平分布执行负载在数据量较小的分区情况下执行查询的速度更快。e、 从“梵蒂冈城”得到的人口返回速度非常快,而不是搜索整个世界的人口。欺骗:小分区创建太多的可能性-目录太多。对给定分区的低容量数据有效。但是,一些查询(如GROUPBY)在高数据量上仍然需要很长时间才能执行。e、 与梵蒂冈的人口分组相比,中国的人口分组需要很长时间。分区并不能解决数据向特定分区值倾斜时的响应问题。Hive扣:bucketing将数据分解为更易于管理或相等的部分。通过分区,可以基于列值创建多个小分区。如果您选择bucketing,则会限制存储数据的bucket数。这个数字是在表创建脚本期间定义的。赞成的意见由于每个分区中的数据量相等,所以在Map端的连接将更快。更快的查询响应(如分区)欺骗您可以在创建表的过程中定义存储桶的数量,但加载等量的数据必须由程序员手动完成。
yuvru6vn4#
前面的解释中缺少一些细节。为了更好地理解分区和bucketing是如何工作的,您应该了解数据是如何存储在hive中的。假设你有一张table
CREATE TABLE mytable ( name string, city string, employee_id int ) PARTITIONED BY (year STRING, month STRING, day STRING) CLUSTERED BY (employee_id) INTO 256 BUCKETS
然后配置单元将数据存储在目录层次结构中,如
/user/hive/warehouse/mytable/y=2015/m=12/d=02
因此,在分区时必须小心,因为如果您例如按employee\u id进行分区,并且您有数百万个雇员,那么您的文件系统中最终会有数百万个目录。术语“基数”指的是字段可能具有的值的数目。例如,如果你有一个'country'字段,世界上的国家大约是300个,所以基数应该是~300。对于像“timestamp \u ms”这样每毫秒改变一次的字段,基数可以是数十亿。一般来说,当选择一个字段进行分区时,它不应该具有很高的基数,因为最终会导致文件系统中的目录太多。另一方面,集群(也称为bucketing)将产生固定数量的文件,因为您确实指定了bucket的数量。hive将要做的是获取字段,计算一个哈希,并将一个记录分配给该bucket。但是,如果使用256个bucket,并且要bucketing的字段基数很低(例如,它是美国的一个州,所以只能有50个不同的值),会发生什么呢?您将有50个有数据的bucket,206个没有数据的bucket。有人已经提到分区如何显著地减少您查询的数据量。所以在我的示例表中,如果您只想从某个日期开始查询,那么按年/月/日进行分区将显著减少io的数量。我认为有人还提到了bucketing如何加速与其他具有完全相同bucketing的表的联接,因此在我的示例中,如果要在同一个employee\u id上联接两个表,hive可以逐个bucket进行联接(如果它们已经按employee\u id排序,则效果更好,因为它将合并已排序的部分,在线性时间内工作(即o(n))。因此,当字段具有较高的基数并且数据均匀分布在bucket之间时,bucketing工作得很好。当分区字段的基数不太高时,分区工作得最好。此外,您可以使用订单(年/月/日是一个很好的例子)对多个字段进行分区,而您只能对一个字段进行bucket。
6qqygrtg5#
Partitioning
select * from sales_table where product_id='P1'
避免全表扫描,只读取与 product_id='P1' 我们可以基于 product_id 列。这样,配置单元表的文件将被拆分为两个文件,一个带有 product_id='P1' 其他的有 product_id='P2' . 现在,当我们执行上述查询时,它将只扫描 product_id='P1' 文件。
product_id='P1'
product_id
product_id='P2'
../hive/warehouse/sales_table/product_id=P1 ../hive/warehouse/sales_table/product_id=P2
下面给出了创建分区的语法。注意,我们不应该使用 product_id 列定义以及以下语法中的非分区列。这应该只在 partitioned by 条款。
partitioned by
create table sales_table(sales_id int,trans_date date, amount int) partitioned by (product_id varchar(10))
缺点:分区时要非常小心。也就是说,它不应该用于重复值数量非常少的列(尤其是主键列),因为它增加了分区文件的数量并增加了系统的开销 Name node .木扣
Name node
rqqzpn5f6#
-------- Bucketing 是用来克服 cons 我在分区部分提到的。当列中的重复值很少(例如-主键列)时,应使用此选项。这类似于rdbms中主键列索引的概念。在我们的table上,我们可以 Sales_Id 扣件柱。当我们需要查询 sales_id 列。下面是bucketing的语法。
Bucketing
cons
Sales_Id
sales_id
create table sales_table(sales_id int,trans_date date, amount int) partitioned by (product_id varchar(10)) Clustered by(Sales_Id) into 3 buckets
在这里,我们将进一步将数据分割为分区之上的几个文件。因为我们已经指定 3 bucket,它被分成3个文件 product_id . 它内部使用 modulo operator 以确定每个 sales_id 应该保存。例如,对于 product_id='P1' ,的 sales_id=1 将存储在000001\u 0文件中(即1%3=1), sales_id=2 将存储在000002\u 0文件中(即2%3=2), sales_id=3 将存储在0000000文件中(即3%3=0)等。
3
modulo operator
sales_id=1
sales_id=2
sales_id=3
mxg2im7a7#
在进入 Bucketing ,我们需要明白什么 Partitioning 是。让我们以下表为例。请注意,在下面的示例中,我只给出了12条记录供初学者理解。在实时场景中,您可能有数百万条记录。分区
bgibtngc8#
分区数据通常用于水平分布负载,这有利于性能,并有助于以逻辑方式组织数据。例如:如果我们正在处理一个大的 employee 表并经常运行查询 WHERE 将结果限制在特定国家或部门的条款。为了更快的查询响应,可以使用配置单元表 PARTITIONED BY (country STRING, DEPT STRING) . 分区表改变了配置单元构造数据存储的方式,配置单元现在将创建反映分区结构的子目录,如…/employees/country=/dept=xyz。如果查询来自的员工限制 country=ABC ,它将只扫描一个目录的内容 country=ABC . 这可以极大地提高查询性能,但前提是分区方案反映公共过滤。分区特性在hive中非常有用,但是,创建太多分区的设计可能会优化某些查询,但对其他重要查询不利。另一个缺点是分区太多,即大量的hadoop文件和目录是不必要地创建的,而且namenode的开销很大,因为它必须在内存中保留文件系统的所有元数据。bucketing是另一种将数据集分解为更易于管理的部分的技术。例如,假设一个表使用 date 作为顶层分区和 employee_id 因为第二级分区会导致太多的小分区。相反,如果我们将employee表 employee_id 作为bucketing列,此列的值将由用户定义的数字散列到bucket中。具有相同 employee_id 将始终存储在同一个桶中。假设 employee_id 比桶的数量大得多,每个桶都会有很多 employee_id . 在创建表时,您可以指定 CLUSTERED BY (employee_id) INTO XX BUCKETS; 其中xx是桶的数量。扣有几个优点。桶的数量是固定的,因此不会随数据波动。如果两张table被扣住 employee_id ,配置单元可以创建逻辑正确的采样。bucketing也有助于进行有效的Map边连接等。
employee
WHERE
PARTITIONED BY (country STRING, DEPT STRING)
country=ABC
date
employee_id
CLUSTERED BY (employee_id) INTO XX BUCKETS;
8条答案
按热度按时间wwtsj6pe1#
我想我回答这个问题已经晚了,但我的反馈中一直提到这个问题。
navneet提供了极好的答案。添加到它的视觉效果。
分区有助于消除数据,如果在where子句中使用,where-as-bucketing有助于将每个分区中的数据组织成多个文件,因此同一组数据总是写入同一个bucket。有助于很多列的连接。
假设您有一个包含五列的表:name、server\u date、some\u col3、some\u col4和some\u col5。假设您在server\ date上对表进行了分区,并在name列上添加了10个bucket,您的文件结构如下所示。
服务器\日期=xyz
00000_0
00001_0
00002_0
........
00010_0
这里server_date=xyz是分区,000个文件是每个分区中的存储桶。bucket是基于一些散列函数计算的,所以name=sandy的行总是放在同一个bucket中。
92vpleto2#
不同之处在于bucketing按列名划分文件,分区按表中的特定值划分下的文件
希望我的定义是正确的
jq6vz3qz3#
配置单元分区:
分区根据表列的值将大量数据划分为多个片。
假设您存储的是分布在196多个国家的全世界人民的信息,这些国家大约有5亿条条目。如果你想查询来自某个国家(梵蒂冈城)的人,在没有分区的情况下,你必须扫描所有的50亿条条目,甚至要获取一个国家的数千条条目。如果您基于国家对表进行分区,您可以通过只检查一个国家分区的数据来微调查询过程。配置单元分区为列值创建单独的目录。
赞成的意见:
水平分布执行负载
在数据量较小的分区情况下执行查询的速度更快。e、 从“梵蒂冈城”得到的人口返回速度非常快,而不是搜索整个世界的人口。
欺骗:
小分区创建太多的可能性-目录太多。
对给定分区的低容量数据有效。但是,一些查询(如GROUPBY)在高数据量上仍然需要很长时间才能执行。e、 与梵蒂冈的人口分组相比,中国的人口分组需要很长时间。分区并不能解决数据向特定分区值倾斜时的响应问题。
Hive扣:
bucketing将数据分解为更易于管理或相等的部分。
通过分区,可以基于列值创建多个小分区。如果您选择bucketing,则会限制存储数据的bucket数。这个数字是在表创建脚本期间定义的。
赞成的意见
由于每个分区中的数据量相等,所以在Map端的连接将更快。
更快的查询响应(如分区)
欺骗
您可以在创建表的过程中定义存储桶的数量,但加载等量的数据必须由程序员手动完成。
yuvru6vn4#
前面的解释中缺少一些细节。为了更好地理解分区和bucketing是如何工作的,您应该了解数据是如何存储在hive中的。假设你有一张table
然后配置单元将数据存储在目录层次结构中,如
因此,在分区时必须小心,因为如果您例如按employee\u id进行分区,并且您有数百万个雇员,那么您的文件系统中最终会有数百万个目录。术语“基数”指的是字段可能具有的值的数目。例如,如果你有一个'country'字段,世界上的国家大约是300个,所以基数应该是~300。对于像“timestamp \u ms”这样每毫秒改变一次的字段,基数可以是数十亿。一般来说,当选择一个字段进行分区时,它不应该具有很高的基数,因为最终会导致文件系统中的目录太多。
另一方面,集群(也称为bucketing)将产生固定数量的文件,因为您确实指定了bucket的数量。hive将要做的是获取字段,计算一个哈希,并将一个记录分配给该bucket。但是,如果使用256个bucket,并且要bucketing的字段基数很低(例如,它是美国的一个州,所以只能有50个不同的值),会发生什么呢?您将有50个有数据的bucket,206个没有数据的bucket。
有人已经提到分区如何显著地减少您查询的数据量。所以在我的示例表中,如果您只想从某个日期开始查询,那么按年/月/日进行分区将显著减少io的数量。我认为有人还提到了bucketing如何加速与其他具有完全相同bucketing的表的联接,因此在我的示例中,如果要在同一个employee\u id上联接两个表,hive可以逐个bucket进行联接(如果它们已经按employee\u id排序,则效果更好,因为它将合并已排序的部分,在线性时间内工作(即o(n))。
因此,当字段具有较高的基数并且数据均匀分布在bucket之间时,bucketing工作得很好。当分区字段的基数不太高时,分区工作得最好。
此外,您可以使用订单(年/月/日是一个很好的例子)对多个字段进行分区,而您只能对一个字段进行bucket。
6qqygrtg5#
Partitioning
用于在查询数据时获得性能。例如,在上表中,如果我们编写下面的sql,它需要扫描表中的所有记录,这会降低性能并增加开销。避免全表扫描,只读取与
product_id='P1'
我们可以基于product_id
列。这样,配置单元表的文件将被拆分为两个文件,一个带有product_id='P1'
其他的有product_id='P2'
. 现在,当我们执行上述查询时,它将只扫描product_id='P1'
文件。下面给出了创建分区的语法。注意,我们不应该使用
product_id
列定义以及以下语法中的非分区列。这应该只在partitioned by
条款。缺点:分区时要非常小心。也就是说,它不应该用于重复值数量非常少的列(尤其是主键列),因为它增加了分区文件的数量并增加了系统的开销
Name node
.木扣
rqqzpn5f6#
--------
Bucketing
是用来克服cons
我在分区部分提到的。当列中的重复值很少(例如-主键列)时,应使用此选项。这类似于rdbms中主键列索引的概念。在我们的table上,我们可以Sales_Id
扣件柱。当我们需要查询sales_id
列。下面是bucketing的语法。
在这里,我们将进一步将数据分割为分区之上的几个文件。
![](https://i.stack.imgur.com/I95Kg.jpg)
因为我们已经指定
3
bucket,它被分成3个文件product_id
. 它内部使用modulo operator
以确定每个sales_id
应该保存。例如,对于product_id='P1'
,的sales_id=1
将存储在000001\u 0文件中(即1%3=1),sales_id=2
将存储在000002\u 0文件中(即2%3=2),sales_id=3
将存储在0000000文件中(即3%3=0)等。mxg2im7a7#
在进入
![](https://i.stack.imgur.com/J63Ki.jpg)
Bucketing
,我们需要明白什么Partitioning
是。让我们以下表为例。请注意,在下面的示例中,我只给出了12条记录供初学者理解。在实时场景中,您可能有数百万条记录。分区
bgibtngc8#
分区数据通常用于水平分布负载,这有利于性能,并有助于以逻辑方式组织数据。例如:如果我们正在处理一个大的
employee
表并经常运行查询WHERE
将结果限制在特定国家或部门的条款。为了更快的查询响应,可以使用配置单元表PARTITIONED BY (country STRING, DEPT STRING)
. 分区表改变了配置单元构造数据存储的方式,配置单元现在将创建反映分区结构的子目录,如…/employees/country=/dept=xyz。
如果查询来自的员工限制
country=ABC
,它将只扫描一个目录的内容country=ABC
. 这可以极大地提高查询性能,但前提是分区方案反映公共过滤。分区特性在hive中非常有用,但是,创建太多分区的设计可能会优化某些查询,但对其他重要查询不利。另一个缺点是分区太多,即大量的hadoop文件和目录是不必要地创建的,而且namenode的开销很大,因为它必须在内存中保留文件系统的所有元数据。bucketing是另一种将数据集分解为更易于管理的部分的技术。例如,假设一个表使用
date
作为顶层分区和employee_id
因为第二级分区会导致太多的小分区。相反,如果我们将employee表employee_id
作为bucketing列,此列的值将由用户定义的数字散列到bucket中。具有相同employee_id
将始终存储在同一个桶中。假设employee_id
比桶的数量大得多,每个桶都会有很多employee_id
. 在创建表时,您可以指定CLUSTERED BY (employee_id) INTO XX BUCKETS;
其中xx是桶的数量。扣有几个优点。桶的数量是固定的,因此不会随数据波动。如果两张table被扣住employee_id
,配置单元可以创建逻辑正确的采样。bucketing也有助于进行有效的Map边连接等。