你可以不够优秀,但是不要甘于平凡
首先我们可以参考下官方文档,对于创建分桶表的一些描述
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-BucketedSortedTables
分桶是相对分区进行更细粒度的划分。分桶将整个数据内容安装某列属性值得hash值进行区分,如要安装name属性分为3个桶,就是对name属性值的hash值对3取摸,按照取模结果对数据分桶。如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件。桶是比表或分区更为细粒度的数据范围划分。针对某一列进行桶的组织,对列值哈希,然后除以桶的个数求余,决定将该条记录存放到哪个桶中。
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
[CLUSTERED BY (col_name, col_name, ...)
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]
CREATE TABLE page_view(viewTime INT, userid BIGINT,
page_url STRING, referrer_url STRING,
ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
CLUSTERED BY(userid) SORTED BY(viewTime) INTO 32 BUCKETS
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\001'
COLLECTION ITEMS TERMINATED BY '\002'
MAP KEYS TERMINATED BY '\003'
STORED AS SEQUENCEFILE;
In the example above, the page_view table is bucketed (clustered by) userid and within each bucket the data is sorted in increasing order of viewTime. Such an organization allows the user to do efficient sampling on the clustered column - in this case userid. The sorting property allows internal operators to take advantage of the better-known data structure while evaluating queries, also increasing efficiency. MAP KEYS and COLLECTION ITEMS keywords can be used if any of the columns are lists or maps.
The CLUSTERED BY and SORTED BY creation commands do not affect how data is inserted into a table – only how it is read. This means that users must be careful to insert data correctly by specifying the number of reducers to be equal to the number of buckets, and using CLUSTER BY and SORT BY commands in their query.
There is also an example of creating and populating bucketed tables.
先创建分桶表,通过直接导入数据文件的方式
数据准备 student.txt
1001 ss1
1002 ss2
1003 ss3
1004 ss4
1005 ss5
1006 ss6
1007 ss7
1008 ss8
1009 ss9
1010 ss10
1011 ss11
1012 ss12
1013 ss13
1014 ss14
1015 ss15
1016 ss16
创建分桶表
create table stu_buck(id int, name string)
clustered by(id)
into 4 buckets
row format delimited fields terminated by '\t';
查看表结构
hive (default)> desc formatted stu_buck;
Num Buckets: 4
导入数据到分桶表中
hive (default)> load data local inpath '/datas/student.txt' into table stu_buck;
查看创建的分桶表中是否分成 4 个桶,发现并没有分成 4 个桶。是什么原因呢?
直接load data不会有分桶的效果,这样和不分桶一样,在HDFS上只有一个文件。
另一种方法试试呢?
创建分桶表时,数据通过子查询的方式导入
create table stu(id int, name string)
row format delimited fields terminated by '\t';
向普通的 stu 表中导入数据
load data local inpath '/datas/student.txt' into table stu;
清空 stu_buck 表中数据
truncate table stu_buck;
select * from stu_buck;
导入数据到分桶表,通过子查询的方式
insert into table stu_buck
select id, name from stu;
发现还是只有一个分桶。为什么尼?
其实在官网上面已经有所描述了需要配置一个参数才可以de
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL+BucketedTables
需要设置一个属性
hive (default)> set hive.enforce.bucketing=true;
hive (default)> insert into table stu_buck
select id, name from stu;
查询分桶的数据
hive (default)> select * from stu_buck;
OK
stu_buck.id stu_buck.name
1004 ss4
1008 ss8
1012 ss12
1016 ss16
1001 ss1
1005 ss5
1009 ss9
1013 ss13
1002 ss2
1006 ss6
1010 ss10
1014 ss14
1003 ss3
1007 ss7
1011 ss11
1015 ss15
分桶抽样查询
对于非常大的数据集,有时用户需要使用的是一个具有代表性的查询结果而不是全部结果。Hive 可以通过对表进行抽样来满足这个需求。
查询表 stu_buck 中的数据。
hive (default)> select * from stu_buck tablesample(bucket 1 out of 4 on id);
注:tablesample 是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y) 。
y 必须是 table 总 bucket 数的倍数或者因子。hive 根据 y 的大小,决定抽样的比例。例如,table 总共分了 4 份,当 y=2 时,抽取(4/2=)2 个 bucket 的数据,当 y=8 时,抽取(4/8=)1/2个 bucket 的数据。 x 表示从哪个 bucket 开始抽取,如果需要取多个分区,以后的分区号为当前分区号加上 y。
例如,table 总 bucket 数为 4,tablesample(bucket 1 out of 2),表示总共抽取(4/2=)2 个 bucket 的数据,抽取第 1(x)个和第 4(x+y)个 bucket 的数据。
注意:x 的值必须小于等于 y 的值,否则会报错。报错信息如下:
FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table stu_buck
对于非常大的数据集,用户不需要全部查询的结果,只需要一个代表性的查询结果时,可以通过对表进行分桶抽样。
每个桶内的数据是排序的,这样每个桶进行连接时就变成了高效的归并排序
能够有效的根据某一个key,将数据进行分片,方便数据存储和计算
分桶针对的是数据文件,分区针对的是数据目录而非文件
分区提供一个隔离数据和优化查询的便利方式。不过,并非所有的数据集都可形成合理的分区,特别是要确定分区合适的划分大小。
分桶是将数据集分解成更容易管理的若干部分的另一个技术。