【Hive大数据】Hive分区表与分桶表使用详解

news2024/11/25 2:41:50

目录

一、分区概念产生背景

二、分区表特点

三、分区表类型

3.1 单分区

3.2 多分区

四、动态分区与静态分区

4.1 静态分区【静态加载】

4.1.1 操作演示

4.2 多重分区

4.2.1 操作演示

4.3 分区数据动态加载

4.3.1 分区表数据加载 -- 动态分区

4.3.2 操作演示

五、分桶表

5.1 分桶表概念

5.2 分桶规则说明

5.2.1 分桶基本规则

5.3 分桶完整语法树

5.4 分桶表操作演示

5.4.1 创建表

5.4.2 使用分桶表好处


一、分区概念产生背景

使用hive对表进行查询时,比如:select * from t_user where name =' lihua' ,hive执行这条sql的时候,一般会扫描整个表的数据,我们知道全表扫描的效率是很低的,尤其是对于hive这种最终数据的查询要走hdfs文件全表扫描效率就更低了。

事实上,在很多情况下,业务中需要查询的数据并不需要全表扫描,而是能够预知查询的数据在一定的区域中,基于这个前提,hive在建表的时候就引入了partition(分区)的概念。对应建表语法树位置如下:

二、分区表特点

分区表指的是在创建表时指定的partition的分区空间,如果需要创建有分区的表,需要在create表的时候调用可选参数partitioned by;

  • 一个表可以拥有一个或者多个分区,每个分区以文件夹的形式单独存在表文件夹的目录下;

  • 表和列名不区分大小写;

  • 分区是以字段的形式存在于表结构中,通过desc formatted table命令可以查看到字段存在,但该字段不存放实际的数据内容,仅仅是分区的表示;

三、分区表类型

分区表根据建表时分区字段数分为单分区表和多分区表,如下:

3.1 单分区

单分区就是说在表文件夹目录下只有一级文件夹目录,建表的时候PARTITIONED BY里面的字段只有一个,如下,按照省份单分区;

create table t_user_province (
    id int, 
    name string,
    age int
) partitioned by (province string);

3.2 多分区

另外一种是多分区,表文件夹下出现多文件夹嵌套模式,建表的时候可以根据业务需要指定多个分区字段,如下为三分区表,按省份、市、县分区;

create table t_user_province_city_county (
    id int, 
    name string,
    age int
) partitioned by (province string, city string,county string);

四、动态分区与静态分区

4.1 静态分区【静态加载】

静态分区指的是分区的属性值,是由用户在加载数据的时候手动指定的,语法:

load data [local] inpath 'filepath ' into table tablename partition(分区字段='分区值'...);

注意:

Local参数用于指定待加载的数据是位于本地文件系统还是HDFS文件系统;

4.1.1 操作演示

创建分区表

创建一张分区表t_all_hero_part,以role角色作为分区字段;

create table t_all_hero_part(
   id int,
   name string,
   hp_max int,
   mp_max int,
   attack_max int,
   defense_max int,
   attack_range string,
   role_main string,
   role_assist string
) partitioned by (role string)
row format delimited
fields terminated by "\t";

执行上面的sql进行分区表的创建;

可以看到,在这张表中多出来了一个role的分区字段;

上传本地数据到服务器目录

上传下面的本地测试数据文件到指定目录

将数据加载到hive

使用下面的命令加载本地数据文件到hive表

load data local inpath '/usr/local/soft/hivedata/archer.txt' into table t_all_hero_part partition(role='sheshou');
load data local inpath '/usr/local/soft/hivedata/assassin.txt' into table t_all_hero_part partition(role='cike');
load data local inpath '/usr/local/soft/hivedata/mage.txt' into table t_all_hero_part partition(role='fashi');
load data local inpath '/usr/local/soft/hivedata/support.txt' into table t_all_hero_part partition(role='fuzhu');
load data local inpath '/usr/local/soft/hivedata/tank.txt' into table t_all_hero_part partition(role='tanke');
load data local inpath '/usr/local/soft/hivedata/warrior.txt' into table t_all_hero_part partition(role='zhanshi');

执行过程

检查数据,可以看到数据成功映射到分区表中,重点注意最后那一列正是分区字段;

同时,在HDFS目录下的数据展示如下结构

静态分区表的数据存放很有规律可循,外层以分区名称为目录,内层才是当前这个分区的具体数据文件;

这个与普通的非分区表的区别一目了然,就不再赘述了,通过这种直观的方式可以进一步对分区表的概念做如下理解:

  • 分区的概念提供了一种将Hive表数据分离为多个文件/目录的方法;

  • 不同分区对应着不同的文件夹,同一分区的数据存储在同一个文件夹下;

  • 查询过滤的时候只需要根据分区值找到对应的文件夹,扫描本文件夹下本分区下的文件即可,避免全表数据扫描;

  • 这种指定分区查询的方式叫做分区裁剪;

此时,如果使用下面的这条sql进行查询,就可以先定位到分区,然后只查询这个分区下的这个数据文件,这样一来就不用走全表扫描,效率大大提升了;

select * from t_all_hero_part where role="sheshou" and hp_max >6000;

4.2 多重分区

通过建表语句中关于分区的相关语法可以发现,Hive支持多个分区字段:

PARTITIONED BY (partition1 data_type, partition2 data_type,….)

多重分区下,分区之间是一种递进关系,可以理解为在前一个分区的基础上继续分区,从HDFS的角度来看就是文件夹下继续划分子文件夹。比如:把全国人口数据首先根据省进行分区,然后根据市进行划分,如果你需要甚至可以继续根据区县再划分,此时就是3分区表。

4.2.1 操作演示

创建两个分区表

创建一个双分区表,按照省份与城市划分

create table t_user_province_city (id int, name string,age int) partitioned by (province string, city string);

创建一个三分区表,按照省、市、县划分

create table t_user_province_city_county (id int, name string,age int) partitioned by (province string, city string,county string);

4.3 分区数据动态加载

上面使用load的方式手动指定分区数据的方式也叫做静态分区(静态加载),实际使用中,如果创建的分区非常多,就意味着要使用load命令加载很多次,这样效率必然很低,这时就可以考虑使用hive的动态分区;

4.3.1 分区表数据加载 -- 动态分区

  • 所谓动态分区指的是分区的字段值是基于查询结果(参数位置)自动推断出来的。核心语法就是insert+select;

启用hive动态分区,需要在hive会话中设置两个参数:

#是否开启动态分区功能
set hive.exec.dynamic.partition=true;
​
#指定动态分区模式,分为nonstick非严格模式和strict严格模式
#strict严格模式要求至少有一个分区为静态分区
set hive.exec.dynamic.partition.mode=nonstrict;
​

4.3.2 操作演示

创建一张新的分区表,执行动态分区插入,sql建表语句如下

create table t_all_hero_part_dynamic(
    id int,
    name string,
    hp_max int,
    mp_max int,
    attack_max int,
    defense_max int,
    attack_range string,
    role_main string,
    role_assist string
) partitioned by (role string)
row format delimited
fields terminated by "\t";

在执行上面的sql之前,需要在当前会话下设置如下参数:

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

创建完成后,执行下面的sql将上一张表的数据进行导入

insert into table t_all_hero_part_dynamic partition(role) select tmp.*,tmp.role_main from t_all_hero tmp;

执行的时间可能有点长

 

查看hdfs上该动态表的目录,可以看到也是按照预期的分区字段将数据文件做了划分;

分区表的注意事项:

  • 分区表不是建表的必要语法规则,是一种优化手段表,可选;

  • 分区字段不能是表中已有的字段,不能重复;

  • 分区字段是虚拟字段,其数据并不存储在底层的文件中;

  • 分区字段值的确定来自于用户价值数据手动指定(静态分区)或者根据查询结果位置自动推断(动态分区);

  • Hive支持多重分区,也就是说在分区的基础上继续分区,划分更加细粒度;

五、分桶表

5.1 分桶表概念

分桶表也叫做桶表,叫法源自建表语法中bucket单词,是一种用于优化查询而设计的表类型,分桶表对应的数据文件在底层会被分解为若干个部分,通俗来说就是被拆分成若干个独立的小文件,在分桶时,要指定根据哪个字段将数据分为几桶(几个部分);

5.2 分桶规则说明

5.2.1 分桶基本规则

桶编号相同的数据会被分到同一个桶当中;

Bucket number = hash_function(bucketing_column)  mod   num_buckets
      分桶编号  = 哈希方法(分桶字段)                取模  分桶个数

hash_function取决于分桶字段bucketing_column的类型:

  • 如果是int类型,hash_function(int) == int;

  • 如果是其他比如bigint,string或者复杂数据类型,hash_function比较棘手,将是从该类型派生的某个数字,比如hashcode值;

5.3 分桶完整语法树

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]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 DELIMITED|SERDE serde_name WITH SERDEPROPERTIES (property_name=property_value,...)]
[STORED AS file_format]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)];

分桶关键参数说明:

  • CLUSTERED BY (col_name)表示根据哪个字段进行分;

  • INTO N BUCKETS表示分为几桶(也就是几个部分);

  • 需要注意的是,分桶的字段必须是表中已经存在的字段;

最简单的分桶sql

CREATE [EXTERNAL] TABLE [db_name.]table_name
[(col_name data_type, ...)]
CLUSTERED BY (col_name)
INTO N BUCKETS;

5.4 分桶表操作演示

需求,有如下数据文件,

文件内容解读:

  • 内容展示了美国2021-1-28号,各个县county的新冠疫情累计案例信息,包括确诊病例和死亡病例;

  • 字段含义:count_date(统计日期),county(县),state(州),fips(县编码code),cases(累计确诊病例),deaths(累计死亡病例);

5.4.1 创建表

分桶的字段一定要是表中已经存在的字段

无字段排序的分桶表

根据state字段把数据分为5桶,建表语句如下:

CREATE TABLE t_usa_covid19_bucket(
      count_date string,
      county string,
      state string,
      fips int,
      cases int,
      deaths int)
CLUSTERED BY(state) INTO 5 BUCKETS; 

带有字段排序的分桶表

根据state字段分为5桶 每个桶内根据cases确诊病例数倒序排序

CREATE TABLE t_usa_covid19_bucket_sort(
     count_date string,
     county string,
     state string,
     fips int,
     cases int,
     deaths int)
CLUSTERED BY(state)
sorted by (cases desc) INTO 5 BUCKETS;

创建成功后查看hdfs,可以看到表的相关数据目录;

注意:向hive的分桶表导入数据时不能再直接使用hdfs的命令直接加载数据文件到表的目录,需要通过insert + select的方式;

为了导入数据到上面创建的分桶表,先创建一个普通的表,建表sql如下:

CREATE TABLE t_usa_covid19(
       count_date string,
       county string,
       state string,
       fips int,
       cases int,
       deaths int)
row format delimited fields terminated by ",";

上传数据文件到该表;

hdfs dfs -put ./us-covid19-counties.dat /user/hive/warehouse/test.db/t_usa_covid19

执行成功后,检查该表数据,可以看到数据加载成功;

使用insert+select语法将数据加载到分桶表中

insert into t_usa_covid19_bucket select * from t_usa_covid19;

看到这个map-reduce任务完成之后,再去检查分桶表数据,此时数据就加载进去了;

到HDFS上查看t_usa_covid19_bucket底层数据结构可以发现,数据被分为了5个部分,并且从结果可以发现,分桶字段一样的数据就一定被分到同一个桶中;

接下来做一个测试吧,基于分桶字段state查询来自于New York州的数据,既然数据按照state(州)进行了分桶,查询的时候,就不再需要进行全表扫描过滤,底层来说,查询的时候,将根据分桶的规则hash_function(New York) mod 5计算出分桶编号,查询指定分桶里面的数据 就可以找出结果 此时是分桶扫描而不是全表扫描;

select * from t_usa_covid19_bucket where state="New York";

从查询速度来说还是很快的;

5.4.2 使用分桶表好处

基于分桶字段查询时,减少全表扫描

分桶之后,如果按照分桶字段进行筛选,数据量明显减少了,就可以避免全表的扫描而提升查询效率;

JOIN时可以提高MR程序效率,减少笛卡尔积数量

正常两表关联查询,比如 select a.* from a join b on a.id = b.id ...这样的查询时,如果不走分桶表,其底层一定是按照笛卡尔积的数量进行数据扫描与查询,而对于分桶表来说,如果on后面的字段正好是分桶字段的话,查询的数据就会在确定的桶中进行,数据量减少了,所以笛卡尔积数量也会大大减少;

使用分桶表对数据进行高效抽样

当数据量特别大时,对全体数据进行处理存在困难时,抽样就显得尤其重要了。抽样可以从被抽取的数据中估计和推断出整体的特性,是科学实验、质量检验、社会调查普遍采用的一种经济有效的工作和研究方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/499514.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql事务及搜索引擎

mysql事务后半部分 加快查询速度索引会自动排序,(升序) select * from t1;全盘扫描 where可以索引查找show create table 索引是一个排序的列表,包含字段值和相应行数据的物理地址 事务是一种机制,一个…

Misc小总结

Misc分类 个人认为Misc中的题目可分为七大类,图片隐写,音视频隐写,其它隐写(PPT、word文档等隐写),压缩包破解,流量分析,取证,编码或密码。这里面涉及的知识点当然是很多的,有很多你…

大学毕业设计使用python制作

前言:相信看到这篇文章的小伙伴都或多或少有一些编程基础,懂得一些linux的基本命令了吧,本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python:一种编程语言&…

Python标准数据类型-字符串常用方法(上)【文末送书】

✅作者简介:CSDN内容合伙人、阿里云专家博主、51CTO专家博主、新星计划第三季python赛道Top1 📃个人主页:hacker707的csdn博客 🔥系列专栏:零基础入门篇 💬个人格言:不断的翻越一座又一座的高山…

经验总结:(Redis NoSQL数据库快速入门)

一、Nosql概述 为什么使用Nosql 1、单机Mysql时代 90年代,一个网站的访问量一般不会太大,单个数据库完全够用。随着用户增多,网站出现以下问题 数据量增加到一定程度,单机数据库就放不下了数据的索引(B Tree),一个机…

【Linux】进程的终止,等待(不包含进程的程序替换)

信号的部分会在后面仔细讲,本文不涉及 目录 1.进程终止以及退出码的理解 2.进程退出 3.进程等待 1.进程终止以及退出码的理解 1.情况分类 (1)正常执行完 a.结果正确 b.结果不正确 反思为什么? (2&#xff…

CesiumForUnreal去掉左下角的Ion Logo

文章目录 1.实现目标2.实现过程3.参考资料1.实现目标 记录一下使用CesiumForUnreal插件过程中如何清除左下角的Cesium Ion Logo,清除前后的对比截图如下所示。 原始样式去除后2.实现过程 记录一下实现的过程(含踩坑记录,可能有一点啰嗦)。 (1)首先看一下是哪个蓝图添加的…

【STM32CubeMX】F103窗口看门狗

前言 本文记录了我学习STM32CubeMX的过程,方便以后回忆。我们使用的开发板是基于STM32F103C6T6的。本章记录了窗口看门狗的使用配置。要学习的话,注意流程一说,省略的内容。 基础 窗口看门狗(WWDG)属于APB1上外设。窗口看门狗(WWDG)的时钟源…

【小结】git合并分支总结

首先理清以下几个关系: 1、git有本地库和远程库。 ①本地仓库:也就是电脑上存储的代码,本地代码,一般在某个盘中。 ②远程仓库:是云上的库,比如gitee,github等等。 2、分支:分为本地分支和远…

手机摄影(三)

第七章 构图,用光与色彩 构图的原则: 画面简洁 突出主体 陪体和主体:如果没有枯叶做前景,画面的空间感和深秋氛围会大打折扣。 看到一张你认为很美的照片时,要问自己几个问题: • 这张照片的主体是什么…

jvm之启动参数

写在前面 本文一起看下jvm启动参数相关内容,通过本文希望我自己也希望大家能够真正的应用到实际的工作中。 1:基本内容介绍 一般我们启动java程序有两种方式,一种是直接运行一个有main函数的class,第二种是运行一个在MANIFEST文…

安装mysql

1、环境(虚拟机新安装的Redhat): 链接:https://pan.baidu.com/s/1jjdimuq-TrS8RASqGiU5Xg 提取码:2hef 2、检查系统是否已经安装了 MySQL rpm -aq | grep mysql 如果有旧版本就需要像下面卸载mariadb一样卸载掉。M…

希尔密码,云影密码 及例题

希尔密码 云影密码 题一 [HDCTF2023]–爬过小山去看云 题目描述: 密文:ymyvzjtxswwktetpyvpfmvcdgywktetpyvpfuedfnzdjsiujvpwktetpyvnzdjpfkjssvacdgywktetpyvnzdjqtincduedfpfkjssne 在山的那头,有3个人,4只鸟,19只…

Keepalived概念与安装部署过程

前言 目前互联网上主流高可用方案软件有keepalived、heartbeat,其中heartbeat是比较早期用来实现高可用软件的,而keepalived是目前轻量级,并且管理方便、易使用的高可用解决方案。 1.1 Keeplived高可用的功能 Keepalived是一个类似于工作在…

半监督学习经典工作:边缘生成对抗网络(MarginGAN)

来源:投稿 作者:小灰灰 编辑:学姐 论文标题:MarginGAN: Adversarial Training in Semi-Supervised Learning 论文链接: https://papers.nips.cc/paper/2019/file/517f24c02e620d5a4dac1db388664a63-Paper.pdf 代码链接&#xf…

ShardingCore安装笔记

由于本人采用Visual Studio的nuget管理器安装ShardingCore经常出现网络错误的问题,所以采用离线包的方式安装插件。 nueget包下载地址:NuGet Gallery | ShardingCore 7.7.1.8 ShardingCore使用版本7.7.1.7 1、下载各种依赖文件,并存放到系…

openTCS分析

一、openTCS概览 1. openTCS操作流程 打开ModelEditor设置点、路线、装货卸货等信息并保存模型打开Kernel和KernelControlCenter在ModelEditor上传模型打开KernelControlCenter设置车辆信息打开OperationsDesk打开OperationsDesk设置小车模式为可利用,并创建订单 …

USB 断开检测

文章目录 USB 断开检测带 Vbus 检测功能的 USB 设备断开不带 Vbus 检测功能的 USB 设备断开USB 设备端断开的检测USB 主机端断开的检测低速/全速设备高速设备 USB 断开检测 USB 主机和 USB 设备同样需要具有检测断开的能力。 USB 主机如果不能检测到 USB 设备的移除将会导致其…

测试虚拟驱动vivi

测试虚拟驱动vivi 文章目录 测试虚拟驱动vivi安装xawtv方法1方法2测试USB摄像头 测试虚拟摄像头vivi1.确定ubuntu的内核版本2. 去www.kernel.org下载同版本的内核修改Makefile测试体验 安装xawtv 方法1 sudo apt-get install xawtv方法2 源码xawtv-3.95.tar.gz: http://www.…

「2023最新」「阿米洛 VARMILO」双模机械键盘使用指南(快捷键组合)

前言 在说明书找不到的时候却需要使用键盘的某些特性时查一下 以阿米洛 minilo 尤加利为例 主要快捷键组合 开机 2 秒内连续敲击空格键三下,数字 1 或 2 或 3 键灯闪烁,键盘开机重新配对 长按 5 秒 Fn Q / W / E 键 (分别对应数字 1 / 2…