打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Hive之分区(Partitions)和桶(Buckets)

hive引入partition和bucket的概念,中文翻译分别为分区和桶(我觉的不是很合适,但是网上基本都是这么翻译,暂时用这个吧),这两个概念都是把数据划分成块,分区是粗粒度的划分桶是细粒度的划分,这样做为了可以让查询发生在小范围的数据上以提高效率。

首先介绍分区的概念,还是先来个例子看下如果创建分区表:

[code lang=”sql”]

create table logs_partition(ts bigint,line string) –ts timestamp line 每一行日志

partitioned by (dt string,country string) — 分区列 dt 日志产生日期

[/code]

创建分区表需要在定义表的时候声明分区列,这个分区列是个比较有意思的东西下面来看看,向表中导入数据:

[code lang=”sql”]

load data local inpath ‘input/hive/partitions/file1′

into table logs_partition

partition(dt=’2001-01-01′,country=’GB’);

…….

— 看下表的结构

hive> desc logs_partition;

OK

ts bigint None

line string None

dt string None

country string None

# Partition Information

# col_name data_type comment

dt string None

country string None

Time taken: 0.265 seconds, Fetched: 10 row(s)

查看一个表的所有分区

hive> show partitions logs_partition;

OK

dt=2001-01-01/country=GB

dt=2001-01-01/country=US

dt=2001-01-02/country=GB

dt=2001-01-02/country=US

Time taken: 0.186 seconds, Fetched: 4 row(s)

[/code]

导入完数据后看下hive数据仓库表logs_partition下的文件目录结构

/user/hive/warehouse/logs_partition

看到了吧分区列都成了目录了,这样查询的时候就会定位到某个目录下而大大提高了查询效率,在查看表结构的时候分区列跟其他列并无区别,看个查询语句:

[code lang=”sql”]

SELECT ts, dt, line

FROM logs

WHERE country=’GB’;

1 2001-01-01 Log line 1

2 2001-01-01 Log line 2

4 2001-01-02 Log line 4

Time taken: 36.316 seconds, Fetched: 3 row(s)

[/code]

这个查询只会查询file1, file2, file4这三个文件还有一个有趣的问题就是,查看下数据文件fieldX

里面都只包含两列ts和line并不包含dt和country这两个分区列,但是从查询结果看分区列和非分区列并无差别,实际上分区列都是从数据仓库的分区目录名得来的。

接下来说说桶,桶是更为细粒度的数据范围划分,它能使一些特定的查询效率更高,比如对于具有相同的桶划分并且jion的列刚好就是在桶里的连接查询,还有就是示例数据,对于一个庞大的数据集我们经常需要拿出来一小部分作为样例,然后在样例上验证我们的查询,优化我们的程序。

下面看看如何创建带桶的表

[code lang=”sql”]

create table bucket_user (id int,name string)

clustered by (id) into 4 buckets;

[/code]

关键字clustered声明划分桶的列和桶的个数,这里以用户的id来划分桶,划分4个桶。

以下为了简便划分桶的列简称为桶列

hive会计算桶列的hash值再以桶的个数取模来计算某条记录属于那个桶

向这种带桶的表里面导入数据有两种方式,一种是外部生成的数据导入到桶表,一种是利用hive来帮助你生成桶表数据

由于hive在load数据的时候不能检查数据文件的格式与桶的定义是否匹配,如果不匹配在查询的时候就会报错,所以最好还是让hive来帮你生成数据,简单来说就是利用现有的表的数据导入到新定义的带有桶的表中,下面来看看:

已经存在的表:

[code lang=”bash”]

hive> select * from users;

OK

0 Nat

2 Joe

3 Kay

4 Ann

hive> set hive.enforce.bucketing=true –必须设置这个数据,hive才会按照你设置的桶的个数去生成数据

[/code]

下面把user的数据导入到bucketed_users中

[code language=”lang='sql”]

insert overwrite table bucketed-users

select * from users;

[/code]

然后见证奇迹的时刻:

[code lang=”bash”]

hive> dfs -ls /user/hive/warehouse/bucketed_users;

-rw-r–r– 1 root supergroup 12 2013-10-10 18:48 /user/hive/warehouse/bucketed_users/000000_0

-rw-r–r– 1 root supergroup 0 2013-10-10 18:48 /user/hive/warehouse/bucketed_users/000001_0

-rw-r–r– 1 root supergroup 6 2013-10-10 18:48 /user/hive/warehouse/bucketed_users/000002_0

-rw-r–r– 1 root supergroup 6 2013-10-10 18:48 /user/hive/warehouse/bucketed_users/000003_0

hive> dfs -cat /user/hive/warehouse/bucketed_users/000000_0;

0Nat

4Ann

[/code]

下面来看看利用bucket来对示例数据进行查询

[code lang=”sql”]

—带桶的表

select * from bucketed_users

tablesample(bucket 1 out of 4 on id);

—不带桶的表

select * from users

tablesample(bucket 1 out of 4 on rand());

[/code]

tablesample的作用就是让查询发生在一部分桶上而不是整个数据集上,上面就是查询4个桶里面第一个桶的数据

相对与不带桶的表这无疑是效率很高的,因为同样都是需要一小部分数据,但是不带桶的表需要使用rand()函数,需要在整个数据集上检索。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Hive 基础之:分区、桶、Sort Merge Bucket Join
大数据学习路线分享分区和分桶
Hive表的分区与分桶
hive学习笔记
hive bucket
Hive中的桶表入门(适用于抽样查询)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服