学习HQL

news/2024/11/15 8:20:54/

4.5 分区表

分区表实际上就是将表中的数据以某种维度进行划分文件夹管理 ,当要查询数据的时候,根据维度直接加载对应文件夹下的数据! 不用加载整张表所有的数据再进行过滤, 从而提升处理数据的效率!

比如在一个学生表中想查询某一个年级的学生,如果不分区,需要在整个数据文件中全表扫描,但是分区后只需要查询对应分区的文件即可.

4.5.1 静态分区

所谓静态分区指的是分区的属性值是由用户在加载数据的时候手动指定的

1.创建单分区表:

-- 创建学生表 分区字段为年级grade
CREATE TABLE  t_student (sid int,sname string) partitioned by(grade int)   -- 指定分区字段
row format delimited fields terminated by ',';
-- 注意∶分区字段不能是表中已经存在的字段,因为分区字段最终也会以虚拟字段的形式显示在表结构上。
select * from t_student;
+----------------+------------------+------------------+
| t_student.sid  | t_student.sname  | t_student.grade  |
+----------------+------------------+------------------+
+----------------+------------------+------------------+
stu01.txt
1,zhangsan,1
2,lisi,1
3,wangwu,1
​
stu02.txt
4,zhaoliu,2
5,lvqi,2
6,maba,2
​
stu03.txt
7,liuyan,3
8,tangyan,3
9,jinlian,3
-- 静态分区需要用户手动加载数据 并指定分区
load  data local  inpath '/root/stu01.txt' into table t_student partition(grade=1);
load  data local  inpath '/root/stu02.txt' into table t_student partition(grade=2);
load  data local  inpath '/root/stu03.txt' into table t_student partition(grade=3);
-- 查询
select * from t_student where grade=1;
+----------------+------------------+------------------+
| t_student.sid  | t_student.sname  | t_student.grade  |
+----------------+------------------+------------------+
| 1              | zhangsan         | 1                |
| 2              | lisi             | 1                |
| 3              | wangwu           | 1                |
+----------------+------------------+------------------+

注意:文件中的数据放入到哪个分区下就属于当前分区的数据,即使数据有误,也会按照当前分区处理

stu03.txt
7,liuyan,3
8,tangyan,3
9,jinlian,3
10.aaa,4
​
load  data local  inpath '/root/stu03.txt' overwrite into table t_student partition(grade=3);
​
select * from t_student where grade=3;
-- 最后一条记录虽然写的是4 但是 放到了年级3分区下 效果也是年级3
+----------------+------------------+------------------+
| t_student.sid  | t_student.sname  | t_student.grade  |
+----------------+------------------+------------------+
| 7              | liuyan           | 3                |
| 8              | tangyan          | 3                |
| 9              | jinlian          | 3                |
| 10             | aaa              | 3                |
+----------------+------------------+------------------+

2.创建多分区表

-- 创建学生表 分区字段为年级grade 班级clazz
CREATE TABLE  t_student02 (sid int,sname string) partitioned by(grade int,clazz int)   -- 指定分区字段
row format delimited fields terminated by ',';
1年级1班
stu0101.txt  
1,zhangsan,1,1
2,lisi,1,1
​
1年级2班
stu0102.txt
3,wangwu,1,2
​
2年级1班
stu0201.txt
4,zhangsan,2,1
5,lisi,2,1
6,maba,2,1
​
3年级1班
stu0301.txt
7,liuyan,3,1
8,tangyan,3,1
3年级2班
9,dalang,3,2
10,jinlian,3,2
load  data local  inpath '/root/stu0101.txt' into table t_student02 partition(grade=1,clazz=1);
load  data local  inpath '/root/stu0102.txt' into table t_student02 partition(grade=1,clazz=2);
load  data local  inpath '/root/stu0201.txt' into table t_student02 partition(grade=2,clazz=1);
load  data local  inpath '/root/stu0301.txt' into table t_student02 partition(grade=3,clazz=1);
load  data local  inpath '/root/stu0302.txt' into table t_student02 partition(grade=3,clazz=2);
​
select * from t_student02 where grade=1 and clazz=2;
+------------------+--------------------+--------------------+--------------------+
| t_student02.sid  | t_student02.sname  | t_student02.grade  | t_student02.clazz  |
+------------------+--------------------+--------------------+--------------------+
| 7                | liuyan             | 3                  | 1                  |
| 8                | tangyan            | 3                  | 1                  |
+------------------+--------------------+--------------------+--------------------+

注意:我们既然建立了分区,就要保证分区查询的的命中率,查询尽量使用设置的分区字段去查询.分区虽然避免了全表扫描,但是也可能会产生大量的小文件,有利有弊.

3.分区其他操作(了解)

-- 查看分区 
show partitions t_student02;
-- 添加分区
alter table t_student02 add  partition (grade=4,clazz=1);
-- 删除分区
alter table t_student02 drop  partition (grade=4,clazz=1);

4.5.2 动态分区

静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断.

详细来说:静态分区需要我们自己手动load并指定分区,如果数据很多,那么是麻烦了.而动态分区指的是分区的字段值是基于查询结果(参数位置)自动推断出来的。核心语法就是insert+seclect。

开启动态分区首先要在hive会话中设置如下的参数

-- 临时设置 重新连接需要重新设置
set hive.exec.dynamic.partition=true; 
set hive.exec.dynamic.partition.mode=nonstrict;

其余参数配置如下:

设置为true表示开启动态分区的功能(默认为false) 
--hive.exec.dynamic.partition=true; 
​
设置为nonstrict,表示允许所有分区都是动态的(默认为strict) 严格模式至少有一个静态分区
-- hive.exec.dynamic.partition.mode=nonstrict; 
​
每个mapper或reducer可以创建的最大动态分区个数(默认为100) 
比如:源数据中包含了一年的数据,即day字段有365个值,那么该参数就需要设置成大于365,
如果使用默认 值100,则会报错 
--hive.exec.max.dynamic.partition.pernode=100; 
​
一个动态分区创建可以创建的最大动态分区个数(默认值1000) 
--hive.exec.max.dynamic.partitions=1000; 
​
全局可以创建的最大文件个数(默认值100000) 
--hive.exec.max.created.files=100000; 
​
当有空分区产生时,是否抛出异常(默认false) 
-- hive.error.on.empty.partition=false;

操作步骤

  1. 创建文件并上传

  2. 创建外部表指向文件(相当于临时表)

  3. 创建动态分区表

  4. 查询外部表将数据动态存入分区表中

创建文件并上传
​
student.txt  
​
1,zhangsan,1,1
2,lisi,1,1
3,wangwu,1,2
4,zhangsan,2,1
5,lisi,2,1
6,maba,2,1
7,liuyan,3,1
8,tangyan,3,1
9,dalang,3,2
10,jinlian,3,2
​
-- 将文件上传到hdfs根目录
hdfs dfs -put student.txt  /stu
创建外部表指向文件(相当于临时表)  
create external table t_stu_e(sid int,sname string,grade int,clazz int
)row format delimited fields terminated by ","
location "/stu";
创建动态分区表
create  table  t_stu_d(sid int,sname string
)partitioned by (grade int,clazz int)
row format delimited fields terminated by ",";
​
查询外部表将数据动态存入分区表中
insert overwrite table t_stu_d partition (grade,clazz) select  *  from t_stu_e ;
​
select * from t_stu_d;

4.6 分桶表

概述

分桶表也叫做桶表,叫法源自建表语法中bucket单词,是一种用于优化查询而设计的表类型。

分区提供一个隔离数据和优化查询的便利方式。不过,并非所有的数据集都可形成合理的分区。不合理的数据分区划分方式可能导致有的分区数据过多,而某些分区没有什么数据的尴尬情况 。分桶是将数据集分解为更容易管理的若干部分的另一种技术。

对Hive(Inceptor)表分桶可以将表中记录按分桶键(字段)的哈希值分散进多个文件中,这些小文件称为桶。桶以文件为单位管理数据!分区针对的是数据的存储路径;分桶针对的是数据文件。

分桶的原理

Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。

bucket num = hash_function(bucketing_column) mod   num_buckets分隔编号      哈希方法(分桶字段)              取模   分桶的个数

分桶的好处

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

  2. 根据join的字段对表进行分桶操作,join时可以提高MR程序效率,减少笛卡尔积数量.

  3. 分桶表数据进行高效抽样.数据量大时,使用抽样数据估计和推断整体特性.

分桶表的创建

1.准备person.txt上传到hdfs
2.创建外部表指向person.txt
3.创建分桶表
4.查询外部表将数据加载到分桶表中
person.txt 
public class Test02 {public static void main(String[] args) {for (int i = 1; i <= 10000; i++) {System.out.println(i + "," + "liuyan" + (new Random().nextInt(10000) + 10000));}}
}
​hdfs dfs -mkdir /person
hdfs dfs -put person.txt /person
2.创建外部表指向person.txt
create external table  t_person_e(id int,pname string
) row format delimited fields terminated by ","location "/person";
​
select  * from t_person_e;
create table  t_person(id int,pname string
)clustered by(id) sorted by (pname) into 24 buckets
row format delimited fields terminated by ",";
insert overwrite table t_person select * from t_person_e ;

桶表抽样

-- tablesample是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y) 
-- x表示从哪个bucket开始抽取。例如,table总bucket数为32,tablesample(bucket 3 out of 16)32 / 16  = 2  代表16桶为一组  抽取 第一组的第3桶  抽取第二组的第3桶 也就是第19桶
-- y必须是table总bucket数的倍数或者因子。hive根据y的大小,决定抽样的比例。tablesample(bucket 3 out of 64)32/64 = 2分之一      64桶为一组  不够一组 取第三桶的 前百分之50select * from t_person tablesample(bucket 4 out of 12); 24/12 抽取2桶数据      12桶一组 抽取 第一组第4桶 第二组 第4桶 4+12 =16桶


http://www.ppmy.cn/news/72207.html

相关文章

Android打开/关闭屏幕和设置系统屏幕亮度方法

在有一次处理屏幕的时候&#xff0c;我通过设置值发现怎么都实现不了。 控制屏幕的两种方法&#xff1a; 第一&#xff1a;通过获取PowerManager对象&#xff0c;利用反射。打开/关闭屏幕&#xff0c;上代码&#xff1a; /** * 关闭屏幕 &#xff0c;其实是使系统休眠 * …

FastAPI 的路由介绍及使用

上一篇文章中&#xff0c;我介绍了 FastAPI 框架的安装和 HelloWorld 项目搭建方式。本文将介绍如何使用 Router 路由处理 FastAPI 中的请求。 什么是路由 路由 Router 就像是一个流水线上的线长&#xff0c;协调生产&#xff0c;下达命令给不同的组长进行分工&#xff0c;然…

springboot mybatisplus 分页 (单表分页,wrapper+分页,自定义分页,自定义+连表left join+wrapper分页)

spirngboot + mybatis + mybatisplus 为我们操作数据库提供了方便,mybatisplus 为我们提供了方页插件, 下面我们来看一下它怎么在各种情况下的使用 引入插件 只需要在 springboot 的配置类中 注入 一个mybatisPlusInterceptor, 并添加 PaginationInnerInterceptor就可以了,…

C语言函数大全-- _w 开头的函数(2)

C语言函数大全 本篇介绍C语言函数大全-- _w 开头的函数 1. _wexecl 1.1 函数说明 函数声明函数功能int _wexecl(const wchar_t *path, const wchar_t *arg0, ... /* , const wchar_t *arg1, ..., NULL */);它是一个 Windows 平台下的 C 标准库函数&#xff0c;用于在新进程…

Reactor模式

常见的网络模型 1 服务端-客户端连接原理 服务器编程中通常涉及三类socketfd, 先简单定义一下&#xff1a; connfd:客户端调用connect与服务端建立连接。 listenfd: 服务端的监听套接字。 clientfd:服务端获取的已连接客户端套接字。 2 单线程阻塞模型 单线程阻塞式模型…

37本国产SCI期刊推荐!涵盖9大领域,建议收藏!①

2020年年初国家科技部正式印发《关于破除科技评价中“唯论文”不良导向的若干措施&#xff08;试行&#xff09;》通知&#xff0c;明确要求破除“唯论文”论不良导向&#xff0c;打造中国高质量科技期刊。那么高质量的国产期刊有哪些呢&#xff1f; 一、化学类 1. Chinese J…

UnityVR--Managers--对象池2

目录 前言 对象池及管理器的基本结构 对象池代码 Chunk.cs 对象池管理器代码 ChunkAllocator.cs 使用 总结 前言 经过上一篇对象池1的了解&#xff0c;已经做到了使用Unity自带的ObjectPool进行内存优化。本篇自己构建一个对象池管理器&#xff08;Manager&#xff09;&…

如何调用api接口获取其中的数据

part1.API接口可以运用到的场景&#xff0c;主要包括以下几个方面&#xff1a; 1. 应用程序集成&#xff1a;API可以使不同的应用程序相互之间进行集成&#xff0c;比如将某个应用程序的数据传递给另一个应用程序&#xff0c;或者调用另一个应用程序的功能。 2. 数据共享&#…