Hive中分区和分桶的结构区别
Structure Difference between partitioning and bucketing in hive
我创建了两个 table:
1) 一个用于使用分桶进行分区
2) 仅分桶 table
我知道 Hive 中分区和分桶的概念。但是我有点困惑,因为我读过 'partition creates directory and bucketing creates files'
。我同意第一部分,因为我可以在 HDFS Hive Warehouse 中看到它,但我无法在 HDFS 中看到 ONLY
bucketing table 的任何文件,除了我加载到 table。那么 ONLY
bucketing table 的文件在哪里呢?我能够在分区目录下看到的文件是 eg: 00000_0
的文件,但是这个文件可以用于分区的 table 但是另一个存储桶的 table 呢??
下面是我创建 table 的代码:
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;
我读到存储桶是在我们创建 table.Please 时创建的,如果我遗漏了什么或要去请更正 wrong.Anyone 请帮忙?
这是因为您必须在插入到您的分桶 table 期间强制分桶或为您自己创建分桶。如果要将数据插入存储桶 table,则可以使用以下标志。
set hive.enforce.bucketing = true; -- (Note: Not needed in Hive 2.x onward)
这将强制 Hive 创建存储桶。您应该能够看到与您的存储桶数量相等的文件数量(如果您有足够的记录并且集群列的分布适当)。
更新。 Load 命令不创建任何桶,它只是将数据放入 HDFS。您应该将数据加载到另一个 table 并使用 insert overwrite 语句将数据从一个 table 插入到另一个。
我创建了外部 table 的配置单元(这通常是我的选择)。你可以坚持你的。
请按照以下步骤操作:
创建数据库
CREATE DATABASE IF NOT EXISTS testdb LOCATION '/hivedb/testdb';
创建集群table(分桶table)
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';
创建一个普通的table
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';
按照@lake 在上一个回答中的建议强制分桶
set hive.enforce.bucketing = true;
创建数据文件 ('data.txt')。我用 20 创建了一个数据文件
记录。
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
将数据文件复制到 HDFS 位置
'/hivedb/testdb/employee_plain_table'
./hadoop fs -put ~/so/data.txt /hivedb/testdb/employee_plain_table
运行 一个 select * 命令超过 testdb.Employee_plain_table
select * from testdb.Employee_plain_table;
这应该显示 20 条记录。
使用插入命令
insert overwrite table testdb.employee select * from employee_plain_table;
这应该 运行 一个 map reduce 作业并将记录插入 bucketed
table.
这将创建 5 个文件,因为根据 DDL 我们有 5 个桶
员工 table.
使用命令验证:
./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,所以没有发生分桶。
我创建了两个 table:
1) 一个用于使用分桶进行分区
2) 仅分桶 table
我知道 Hive 中分区和分桶的概念。但是我有点困惑,因为我读过 'partition creates directory and bucketing creates files'
。我同意第一部分,因为我可以在 HDFS Hive Warehouse 中看到它,但我无法在 HDFS 中看到 ONLY
bucketing table 的任何文件,除了我加载到 table。那么 ONLY
bucketing table 的文件在哪里呢?我能够在分区目录下看到的文件是 eg: 00000_0
的文件,但是这个文件可以用于分区的 table 但是另一个存储桶的 table 呢??
下面是我创建 table 的代码:
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;
我读到存储桶是在我们创建 table.Please 时创建的,如果我遗漏了什么或要去请更正 wrong.Anyone 请帮忙?
这是因为您必须在插入到您的分桶 table 期间强制分桶或为您自己创建分桶。如果要将数据插入存储桶 table,则可以使用以下标志。
set hive.enforce.bucketing = true; -- (Note: Not needed in Hive 2.x onward)
这将强制 Hive 创建存储桶。您应该能够看到与您的存储桶数量相等的文件数量(如果您有足够的记录并且集群列的分布适当)。
更新。 Load 命令不创建任何桶,它只是将数据放入 HDFS。您应该将数据加载到另一个 table 并使用 insert overwrite 语句将数据从一个 table 插入到另一个。
我创建了外部 table 的配置单元(这通常是我的选择)。你可以坚持你的。
请按照以下步骤操作:
创建数据库
CREATE DATABASE IF NOT EXISTS testdb LOCATION '/hivedb/testdb';
创建集群table(分桶table)
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';
创建一个普通的table
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';
按照@lake 在上一个回答中的建议强制分桶
set hive.enforce.bucketing = true;
创建数据文件 ('data.txt')。我用 20 创建了一个数据文件 记录。
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
将数据文件复制到 HDFS 位置 '/hivedb/testdb/employee_plain_table'
./hadoop fs -put ~/so/data.txt /hivedb/testdb/employee_plain_table
运行 一个 select * 命令超过 testdb.Employee_plain_table
select * from testdb.Employee_plain_table;
这应该显示 20 条记录。
使用插入命令
insert overwrite table testdb.employee select * from employee_plain_table;
这应该 运行 一个 map reduce 作业并将记录插入 bucketed table.
这将创建 5 个文件,因为根据 DDL 我们有 5 个桶 员工 table.
使用命令验证:
./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,所以没有发生分桶。