草庐IT

Hive分区分桶

华为云官方博客 2023-03-28 原文

分区

分区概念

在逻辑上分区表与未分区表没有区别,在物理上分区表会将数据按照分区键的列值存储在表目录的子目录中,目录名=“分区键=键值”。其中需要注意的是分区键的值不一定要基于表的某一列(字段),它可以指定任意值,只要查询的时候指定相应的分区键来查询即可。我们可以对分区进行添加、删除、重命名、清空等操作。分为静态分区和动态分区两种,静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。详细来说,静态分区的列实在编译时期,通过用户传递来决定的;动态分区只有在 SQL 执行时才能决定。

分区案例

Hive的分区功能可以帮助用户快速的查找和定位,这里我们给出了一个应用场景,通过使用Hive分区功能创建日期和小时分区,快速查找定位对应的用户与IP地址。具体步骤如下:

步骤 1 创建一张分区表,包含两个分区dt和ht分别表示日期和小时:

CREATE TABLE partition_table001 ( name STRING, ip STRING ) PARTITIONED BY (dt STRING, ht STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t";

步骤 2 启用hive动态分区时,需要设置如下两个参数:

set hive.exec.dynamic.partition=true;

set hive.exec.dynamic.partition.mode=nonstrict;

步骤 3 把partition_table001表某个日期分区下的数据(如下图所示)load到目标表partition_table002中。

  • 如果没有目标表则创建目标表partition_table002:

CREATE TABLE IF NOT EXISTS partition_table002 LIKE partition_table001;

  • 如果使用静态分区,必须指定分区的值,如将partition_table001表中日期分区为“20190520”、小时分区为“00”的数据加载入表partition_table002中:

INSERT OVERWRITE TABLE partition_table002 PARTITION (dt='20190520', ht='00') SELECT name, ip FROM partition_table001 WHERE dt='20190520' and ht='00';

查询一下表partition_table002中我们插入的数据,结果如下图所示:

  • 如果希望插入每天24小时的数据,则需要执行24次上面的语句。而使用动态分区会根据select出的结果自动判断数据该load到哪个分区中去,只需要一句语句即可完成,命令及结果如下所示:

INSERT OVERWRITE TABLE partition_table002 PARTITION (dt, ht) SELECT * FROM partition_table001 WHERE dt='20190520';

步骤 4 查看表格partition_table002下的所有分区信息使用如下命令:

SHOW PARTITIONS partition_table002;

或者拥有admin权限的用户使用dfs –ls <表存储目录>命令如下:

dfs -ls hdfs://hacluster/user/hive/warehouse/partition_table002;

说明:
静态分区和动态分区可以混合使用,在动静结合使用时需要注意静态分区值必须在动态分区值的前面,在select中按位置顺序出现在最后(因为静态分区提前产生,动态分区运行时产生)。如果动态分区作为父路径,则子静态分区无法提前生成,会报错为动态分区不能为静态的父路径。当静态分区是动态分区的子分区时,执行DML操作会报错。因为分区顺序决定了HDFS中目录的继承关系,这点是无法改变的。

分桶

分桶概念

对于每一个表或者分区, Hive可以进一步组织成桶,也就是说分桶是更为细粒度的数据范围划分。Hive会计算桶列的哈希值再以桶的个数取模来计算某条记录属于那个桶。把表(或者分区)组织成桶(Bucket)有两个理由:

  1. 获得更高的查询处理效率。桶为表加上了额外的结构,Hive在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用Map端连接(Map-side join)高效的实现。

  2. 使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。

分桶案例

步骤 1 创建一张含有桶的表格,例如创建一个含有四个桶的表格bucketed_table:

CREATE TABLE bucketed_table (id INT, name STRING) CLUSTERED BY (id) INTO 4 BUCKETS;

**步骤 2 ** 设置hive.enforce.bucketing属性为true,以便自动控制上reduce的数量从而适配bucket的个数,推荐命令如下(当然也可以手动设置参数“mapred.reduce.task”去适配bucket的个数,只是多次手动修改会比较麻烦):

set hive.enforce.bucketing = true;

步骤 3 向表里插入准备好的没有划分桶的数据,例如将没有划分桶的表users的数据插入目标表bucketed_table:

INSERT OVERWRITE TABLE bucketed_table SELECT * FROM users;

步骤 4 查看表格bucketed_table下的所有分桶信息,需要拥有admin权限的用户使用dfs –ls <表或分区存储目录>命令如下:

dfs -ls hdfs://hacluster/user/hive/warehouse/bucketed_table;

步骤 5 对桶中的数据进行采样,使用抽样命令TABLESAMPLE(BUCKET x OUT OF y),例如对表格bucketed_table从第一个桶开始抽取1个桶数据量的样本:

SELECT * FROM bucketed_table TABLESAMPLE(BUCKET 1 OUT OF 4 ON id);

说明:
抽样命令TABLESAMPLE(BUCKET x OUT OF y)中,y必须是表格中分桶数的倍数或者因子。Hive根据y的大小,决定抽样的比例。x表示从哪个桶开始抽取。例如,表格的总分桶数为16,tablesample(bucket 3 out of 8),表示总共抽取(16/8=)2个bucket的数据,分别为第3个桶和第(3+8=)11个桶的数据。

本文由华为云发布。

有关Hive分区分桶的更多相关文章

  1. Ruby rpartition 与分区? - 2

    rpartition和partition有什么区别?我已经阅读了文档,但我认为它们是一样的。只是那些出现在后来的ruby​​版本中吗? 最佳答案 以下示例将有助于识别差异:"abccba".partition("b")#=>["a","b","ccba"]"abccba".rpartition("b")#=>["abcc","b","a"]所以区别在于rpartition搜索最右边的匹配项,而不是最左边的匹配项。 关于Rubyrpartition与分区?,我们在StackOverflow

  2. Hive SQL 五大经典面试题 - 2

    目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类

  3. Linux磁盘分区中物理卷(PV)、卷组(VG)、逻辑卷(LV)创建和(LVM)管理 - 2

    文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分

  4. python - 用于从 Python 到 Ruby 查找集合的所有分区的翻译函数 - 2

    我有以下python函数来递归查找集合的所有分区:defpartitions(set_):ifnotset_:yield[]returnforiinxrange(2**len(set_)/2):parts=[set(),set()]foriteminset_:parts[i&1].add(item)i>>=1forbinpartitions(parts[1]):yield[parts[0]]+bforpinpartitions(["a","b","c","d"]):print(p)有人可以帮我把它翻译成ruby​​吗?这是我目前所拥有的:defpartitions(set)ifnots

  5. 大数据之Hadoop数据仓库Hive - 2

    目录:一、简介二、HQL的执行流程三、索引四、索引案例五、Hive常用DDL操作六、Hive常用DML操作七、查询结果插入到表八、更新和删除操作九、查询结果写出到文件系统十、HiveCLI和Beeline命令行的基本使用十一、Hive配置一、简介Hive是一个构建在Hadoop之上的数据仓库,它可以将结构化的数据文件映射成表,并提供类SQL查询功能,用于查询的SQL语句会被转化为MapReduce作业,然后提交到Hadoop上运行。特点:简单、容易上手(提供了类似sql的查询语言hql),使得精通sql但是不了解Java编程的人也能很好地进行大数据分析;灵活性高,可以自定义用户函数(UDF)和

  6. ruby - 在 ruby​​ 中使用索引分区数组 - 2

    我正在寻找一种通过在ruby​​中使用索引来对数组进行分区的优雅方法例如:["a","b",3,"c",5].partition_with_index(2)=>[["a","b",3],["c",5]]到目前为止,我能想到的最好的方法是使用下面的["a","b",3,"c",5].partition.each_with_index{|val,index|index[["a","b",3],["c",5]]还有其他优雅的方法可以实现吗?谢谢! 最佳答案 你可以这样做:["a","b",3,"c",5].partition.with_i

  7. ruby - 计算具有特定子集大小的集合分区 - 2

    给定一个包含n个元素的集合,我需要找到该集合的所有分区,其中有k个大小几乎相等的子集。例如,对于一个有7个元素和3个子集的集合,我只想要分区,其中有两个子集,每个子​​集有2个元素,一个子集有3个元素。我不想要一个包含1、2和4个元素的子集的分区。换句话说,有877possiblepartitions对于一组7个元素,但我只对由2/2/3个元素组成的子集组成的105个(?)分区感兴趣:实际上n大约是35,这意味着大约有2.81*1027个分区,“仅”8,338,573,669,964,101partitionswiththreesubsets.因此,我不可能将它们全部计算出来并费力地找

  8. arrays - 如何根据相邻元素的条件将数组拆分为有限数量的分区 - 2

    假设我有一组数字,例如ary=[1,3,6,7,10,9,11,13,7,24]我想在较小数字跟随较大数字的第一个点之间拆分数组。我的输出应该是:[[1,3,6,7,10],[9,11,13,7,24]]我已经尝试了slice_when,结果非常接近:ary.slice_when{|i,j|i>j}.to_a#=>[[1,3,6,7,10],[9,11,13],[7,24]]但它也在13和7之间拆分,所以我必须加入剩余的数组:first,*rest=ary.slice_when{|i,j|i>j}.to_a[first,rest.flatten(1)]#=>[[1,3,6,7,10],

  9. 使用navicat连接虚拟机的hive - 2

    一、软件准备虚拟机(操作系统为Linux)中已有MySQL、已部署Hive。本地主机(操作系统为Windows)中下载navicat(我用的是navicatpremium15)。PS:其实用sqlyog也是可以连接虚拟机的Hive数据的。在决定用navicat还是sqlyog之前,可以思考这两个问题:①MySQL和hive的区别;②sqlyog和navicat的区别。对于第一个问题,我理解的最直接的区别是:MySQL的数据可以存储在本地,但是hive的数据一定是存储在分布式文件系统上的。尽管hive的操作数据的命令语法与MySQL非常接近,但hive不是MySQL。对于第二个问题,我理解的最直

  10. javascript - 如何找到多重集的所有分区,其中每个部分都有不同的元素? - 2

    假设我们有这样一个数组:myArray=[A,A,B,B,C,C,D,E]我想创建一个算法,以便它可以找到加起来构成整个数组的所有组合,其中没有任何元素重复。示例组合:[A,B,C,D,E][A,B,C][A,B,C,D][A,B,C,E][A,B,C][A,B,C][D,E]说明:[A,B,C][A,B,C][D,E]和[A,B,C][D,E][A,B,C]是相同的组合。此外,子集的顺序也无关紧要。例如[A,B,C]和[B,A,C]应该相同。到目前为止,我没有超越varmyArray=["A","A","B","B","C","C","D","E"]console.log([...n

随机推荐