在hive中填充bucketed表

时间:2014-12-10 22:36:39

标签: hive hiveql

我创建了一个以性别为斗列的hive表。

创建表userinfoBucketed(用户ID INT,年龄INT,性别STRING,职业STRING,邮政编码STRING)CLUSTERED BY(性别)INTO 2 BUCKETS ROW FORMAT DELIMITED FIELDS终止于'|'存储为文本文件;

将以下数据从文本文件加载到表中 (用户ID |年龄|性别|职业|邮政编码):

1 | 24 | M |技术员| 85711

2 | 53 | F |其他| 94043

3 | 23 | M |作家| 32067

4 | 24 | M |技术员| 43537

5 | 33 | F |其他| 15213

6 | 42 | M |执行| 98101

7 | 57 | M |管理员| 91344

8 | 36 | M |管理员| 05201

9 | 29 | M |学生| 01002

10 | 53 | M |律师| 90703

我已将hive.enforce.bucketing属性设置为true; set hive.enforce.bucketing = true;

1,使用load命令将数据插入表时,不会创建存储桶。存储在一个存储桶中的所有数据

将数据本地inpath'/home/mainnode/u.user'加载到表userinfobucketed;

问题1,为什么数据不会分成2个桶?

2,当从其他表中将数据插入表中时,数据存储在2个桶中。这是我执行的命令:

从userinfo中插入userinfobucketed select *,其中gender ='M';

现在,bucket1(000000_0)的数据如下: 1 | 24 | M |技术| 85711 4 | 24 | M |技术| 43537 6 | 42 | M |执行| 98101 7 | 57 | M |管理员| 91344

bucket2(000001_0)有以下数据: 3 | 23 | M |作家| 32067

问题2,我不明白为什么数据存储在2个桶中,即使所有相同的记录具有相同的性别。

然后我再次使用下面的命令将数据插入表中。 插入表userinfobucketed select * from userinfo where gender ='F';

现在又创建了2个额外存储桶(000000_0_copy_1,000001_0_copy_1),并将数据存储到这些存储桶中,而不是将数据插入到现有存储桶中。现在,即使create table配置为2个桶,也会使总桶数达到4个。

问题3;为什么额外的存储桶被创建到复制到现有存储桶中

请澄清

由于 肖恩

2 个答案:

答案 0 :(得分:4)

Q1 为什么这不能插入到一个分段表中?

load data local inpath '/home/mainnode/u.user' into table userinfobucketed;

A1 :查看this tutorial以插入分段表格。 Hive不支持使用LOAD DATA INPATH直接从平面文件加载到分段表,因此您必须先将LOAD数据放入常规表中,然后INSERT OVERWRITE放入您的分段表格中。

Q2 为什么插入的数据会拆分为2个存储桶,即使所有记录的存储桶列都具有相同的值?

A2 :嗯。这是异常行为。您永远不应该看到具有相同存储桶列值的记录被散列到不同的存储桶中。我怀疑你在第一季度尝试上面的LOAD DATA INPATH方法后没有丢弃表并重新创建它。如果是这种情况,将在插入上创建新的存储桶,忽略现有存储桶中的内容,这将引导我们进入下一个问题......

Q3 为什么要创建额外的存储桶而不是插入现有存储桶?

A3 :Hive不会在插入时将新数据附加到文件中。即使你告诉Hive你的表被打破了,它只会散列您当前插入的数据;它没有考虑表中已有的数据。

要保持表定义中设置的存储区数量,每次执行插入操作时都必须将所有数据一起哈希,并使用INSERT OVERWRITE而不是INSERT INTO来覆盖表。

通常,如果您的表被分区,这样做会容易得多,因此每次进行插入时都不会复制和重新整理整个表。说到分区,因为它的基数如此之低,性别更适合作为分区值而不是桶值。 This article在解释这个概念方面做得很好。

答案 1 :(得分:1)

Bucketing由列的哈希驱动。显然M和F产生相同的散列。您可以考虑将性别作为分区键的一部分 - 以确保它们最终位于不同的物理文件中。