Hive中分区和桶的结构差异

7

我创建了两个表:

1)一个用于分区和桶排序
2)仅使用桶排序的表

我知道Hive中分区和桶排序的概念,但我有点困惑,因为我读到过'partition creates directory and bucketing creates files'。我同意第一部分,因为我可以在HDFS Hive Warehouse中看到,但是我无法在HDFS中看到ONLY 桶排序表的任何文件,除了我加载到表中的数据文件。那么ONLY 桶排序表的文件在哪里?我能够看到分区目录下的文件,例如eg: 00000_0,但这个可能是分区表的,那么桶排序表呢?
下面是我创建表的代码:

CREATE TABLE Employee(
ID BIGINT,
NAME STRING, 
SALARY BIGINT,
COUNTRY STRING 
)
CLUSTERED BY(ID) INTO 5 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE;  

加载数据的代码如下:

load data local inpath '/home/cloudera/Desktop/SampleData.txt' into table employee;  

我了解到,当我们创建表时,桶也会被创建。如果我有什么错误或疏漏,请纠正我。请问有人能提供帮助吗?
2个回答

10

我创建了外部Hive表格(通常这是我的选择)。您可以继续使用您的方法。

请按照以下步骤进行:

  1. 创建一个数据库

    CREATE DATABASE IF NOT EXISTS testdb LOCATION '/hivedb/testdb';
    
  2. 创建一个分桶表(聚簇表)

  3. CREATE TABLE testdb.Employee(
    ID BIGINT,
    NAME STRING, 
    SALARY BIGINT,
    COUNTRY STRING 
    )
    CLUSTERED BY(ID) INTO 5 BUCKETS
    ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
    STORED AS TEXTFILE
    LOCATION '/hivedb/testdb/employee';
    
  4. 创建一个简单的表格

    CREATE TABLE testdb.Employee_plain_table(
    ID BIGINT,
    NAME STRING, 
    SALARY BIGINT,
    COUNTRY STRING 
    )
    ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
    STORED AS TEXTFILE
    LOCATION '/hivedb/testdb/employee_plain_table';
    
  5. 按照之前回答中@lake的建议,强制使用分桶(bucketing)

  6. set hive.enforce.bucketing = true;
    
  7. 创建一个数据文件('data.txt')。我创建了一个包含20个记录的数据文件。

  8. 1,AAAAA,1000.00,USA
    2,BBBBB,2000.00,CANADA
    3,CCCCC,3000.00,MEXICO
    4,DDDDD,4000.00,BRAZIL
    5,EEEEE,5000.00,ARGENTINA
    6,DDDDD,6000.00,CHILE
    7,FFFFF,7000.00,BOLIVIA
    8,GGGGG,8000.00,VENEZUELA
    9,HHHHH,9000.00,PERU
    10,IIIII,10000.00,COLOMBIA
    11,JJJJJ,11000.00,EQUADOR
    12,KKKKK,12000.00,URUGUAY
    13,LLLLL,13000.00,PARAGUAY
    14,MMMMM,14000.00,GUYANA
    15,NNNNN,15000.00,NICARAGUA
    16,OOOOO,16000.00,PANAMA
    17,PPPPP,17000.00,COSTA RICA
    18,QQQQQ,18000.00,HAITI
    19,RRRRR,19000.00,DOMINICA
    20,SSSSS,20000.00,JAMAICA
    
  9. 将数据文件复制到HDFS位置'/hivedb/testdb/employee_plain_table'

  10. ./hadoop fs -put ~/so/data.txt /hivedb/testdb/employee_plain_table
    
    在testdb.Employee_plain_table上运行select *命令。
    select * from testdb.Employee_plain_table;
    

    这应该展示20条记录。

  11. 使用插入命令

  12. insert overwrite table testdb.employee select * from employee_plain_table;
    

    这应该会运行一个Map Reduce作业并将记录插入到分桶表中。

    根据员工表的DDL,我们有5个桶,因此会创建5个文件。

  13. 使用命令进行验证:

    ./hadoop fs -ls /hivedb/testdb/employee
    Found 5 items
    -rwxr-xr-x   1 hduser supergroup 95 2017-10-19 11:04 /hivedb/testdb/employee/000000_0
    -rwxr-xr-x   1 hduser supergroup 81 2017-10-19 11:04 /hivedb/testdb/employee/000001_0
    -rwxr-xr-x   1 hduser supergroup 90 2017-10-19 11:05 /hivedb/testdb/employee/000002_0
    -rwxr-xr-x   1 hduser supergroup 88 2017-10-19 11:05 /hivedb/testdb/employee/000003_0
    -rwxr-xr-x   1 hduser supergroup 84 2017-10-19 11:05 /hivedb/testdb/employee/000004_0
    

打开每个文件,与原始数据文件进行比较,您将了解发生了什么。

希望这可以澄清您的疑问! 参考:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL+BucketedTables

更新:您使用了“local”加载,这只是一个复制操作,即将给定的输入文件从源位置复制到目标位置。从“local”加载命令是复制操作,“hdfs”中的命令是移动操作。没有涉及到MapReduce,所以没有进行分桶操作。


{btsdaf} - whatsinthename
但是你能解释一下为什么当我们直接将数据加载到分桶表时,它不会创建文件吗?对此有没有任何解释?因为我找不到任何解释。 - whatsinthename

4

这是因为您必须在插入到分桶表时强制执行分桶,或者自己创建分桶。如果您要将数据插入到分桶表中,可以使用以下标志。

 set hive.enforce.bucketing = true;  -- (Note: Not needed in Hive 2.x onward)

这将强制Hive创建桶。如果您有足够的记录和适当的聚类列分布,您应该能够看到与桶数相等的文件数量。

更新。Load命令不会创建任何桶,它只是将数据放入HDFS中。您应该将数据加载到另一个表中,并使用插入重写语句从一张表插入数据到另一张表中。


谢谢您的回答,但还没有生效。我在创建分桶表之前设置了此属性,然后创建了表并加载了数据,还执行了一个查询,但都无济于事。只有数据文件在Hive仓库中。 - whatsinthename
你需要什么? - whatsinthename
如何创建表格,如何加载数据。 - hlagos
1
更新的答案。问题在于您如何加载数据。 - hlagos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接