百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Hive 分区表 & 数据加载方式,效率提升必备技能

bigegpt 2024-10-12 06:09 7 浏览

1. Hive表数据的导入方式

1.1 本地上传至hdfs

命令:

hdfs dfs -put [文件名] [hdfs绝对路径]

例如:测试文件 test_001.txt 内容如下

在 hdfs 绝对路径:/user/hive/warehouse/mytest.db/ 下有一张表 test_001,建表语句如下:

create table test_001(id string, name string) row format delimited fields terminated by '\t';

使用如下命令将 test_001.txt 的内容上传至 /user/hive/warehouse/mytest.db/test_001 表中

hdfs dfs -put test_001.txt /user/hive/warehouse/mytest.db/test_001

注意:

test_001.txt 文件内容中:数据类型、数据列数、列数之间的分隔符要与 hdfs 中 test_001 表定义的一一对应。


1.2 本地导入

命令:

load data local inpath [本地文件路径] into table [表名];

示例:

load data local inpath '/user/xiaomin.liu/hive_testdata/student.csv' into table student;


含义:

将 /user/xiaomin.liu/hive_testdata 目录下 student.csv 文件的内容加载至 hdfs 中的 student 表中。

注意:

1. student.csv 文件内容中:数据类型、数据列数、列数之间的分隔符要与 hdfs 中 student 表定义的一一对应。

2. 使用本地导入的方式加载数据至 hive,使用的是复制操作,即当本地路径下的文件被加载至 hive 后,该本地路径下的文件依然存在,不会消失。


1.3 hdfs导入

命令:

load data inpath [文件在hdfs中的路径] into table [表名];

示例:

load data inpath '/user/warehouse/test/student.txt' into table student;

含义:

将 hdfs 路径为 /user/warehouse/test 下的 student.txt 文件的数据加载至 hdfs 中的 student 表中。

注意:

使用 hdfs 导入数据至 hive,使用的是剪切操作,即原 hdfs 路径下的文件在被导入至 hive 后,原 hdfs 路径下的文件将不存在了。


1.4 覆盖导入

本地导入命令:

load data local inpath [本地文件路径] overwrite into table [表名];

hdfs导入命令:

load data inpath [hdfs文件路径] overwrite into table [表名];


示例:

本地导入命令:

load data local inpath '/user/xiaomin.liu/hive_testdata/student.csv' overwrite into table student;

hdfs导入命令:

load data inpath '/user/warehouse/test/student.txt' overwrite into table student;


含义:

同1.2中的本地导入和1.3中的 hdfs 导入类似,只是新增的关键字 overwrite 会将表中已有的数据进行覆盖操作。


1.5 查询导入

命令:

create table [目标table_name] as select * from [已存在table_name];

示例:

create table sub_student as select * from student;

含义:将表 student 的结构与数据复制一份给到表 sub_student。


1.6 insert导入

追加模式命令:

insert into table [表名] select * from [已存在table_name];

示例:

insert into table sub_student select * from student;

含义:将表 student 的数据以 append 追加的方式写入表 sub_student 中。


覆盖模式命令:

insert overwrite table [表名] select * from [已存在table_name];

示例:

insert overwrite table sub_student select * from student;

含义:将表 student 的数据以覆盖的方式写入表 sub_student 中。


2. Hive 分区表操作

1.1 分区表的概念

Hive 中分区表的意思是按照表的某一列列名(1个字段)或某几列列名(多个字段)作为类似文件夹的形式来隔离分开存放数据,以便提高检索效率和管理效率。

例如:
公司要收集网站用户登录日志进行用户数据行为分析,假设已存在 /user/login/warehouse/login_record 作为记录登录日志的存储表,如果每天都将日志写入该表,日积月累,login_record 表内容越来越多。

在查询时进行全表扫描耗费的资源会非常多,等待的时间也会特别长。严重影响到了数据分析的效率。

在这种情况下,我们可以采用创建分区表的方法来创建 login_record 表,以日期对login_record 表进行分区,不同日期的日志信息存储到不同的日期分区中。在查询时可指定日期分区来进行查询,可以有效提高查询效率。

简言之,分区表是指在系统上建立文件夹,把不同维度的分类数据放在不同文件夹下面,查询时通过 where 子句过滤,只对指定目录下的内容进行查询,加快查询速度。


1.2 分区表创建语法

分区表 hive sql 创建语句如下:

create table login_logs(l_id string, l_loginName string, l_date string) partitioned by (date string) row format delimited fields terminated by  '\t';


分区表在创建时关键字是:partitioned by

括号里跟上分区字段名及其字段类型,这样在创建表时就指明要创建的是一个分区表,上述创建语句说明要创建一个分区字段为:date,且类型为 string 类型的分区表,表名是 login_logs。


1.3 多分区表创建方式

多分区表 hive sql 创建语句如下:

create table login_logs(l_id string, l_loginName string, l_date string) partitioned by (year string, month string) row format delimited fields terminated by  '\t';


与1.2中分区表创建语句的区别在于关键字 partitioned by 后面的参数是指定了多个分区字段,每个分区字段都需要指定字段类型,多字段之间以逗号分隔。


例如:
dws_test_001_daily_df 表有2个分区字段,分区字段分别是:dt,hotel。

hdfs多分区(文件夹)信息查询:一级分区(文件夹)

命令:

hive>dfs -ls /user/hive/warehouse/dws.db/dws_test_001_daily_df;

上图展示的是一级分区字段:dt,相当于一级文件夹。

hdfs多分区(文件夹)信息查询:二级分区(文件夹)

命令:

hive>dfs -ls /user/hive/warehouse/dws.db/dws_test_001_daily_df/dt=2021-08-09;


上图展示的是二级分区字段:hotel,相当于二级文件夹。

load 数据时可以指定分区来存储目标数据,然后在查询时 where 条件设置 dt 和 hotel 为指定目标值,则可达到缩小数据查询范围的目的,进而提高查询效率。


1.4 查看分区数据

1.查看分区表数据

命令:

select * from login_logs where year='2021' and month='11';

查询 sql 中以分区字段 year 和 month 作为 where 条件进行查询,与普通的 mysql 语句在语法上没有区别,但是在数据底层意义上差异较大,使用分区字段进行条件查询,相当于在指定目录:year='2021' 且 month='11' 下进行数据的搜索。


2.查看分区信息
命令:

show partitions dws.dws_test_001_daily_df partition(dt='2021-10-31');

上图可以看出查询结果为一级分区 dt=2021-10-31下所有二级分区 hotel 的信息。


1.5 分区表加载数据

分区表加载数据的方式与非分区表没有本质区别,只是在语法上有些许变化,具体加载数据的方式可参考上方的 Hive 表数据的导入方式。


示例:
分区表从本地导入 hdfs 语法:

load data local inpath '/user/xiaomin.liu/hive_testdata/login_data.csv' overwrite into table login_logs partition(year='2021', month='10');


含义:

将本地的 login_data.csv 文件内容导入到 hdfs 中 login_logs 表的year='2021',month='10' 的分区中。


1.6 修改分区

命令:

ALTER TABLE table_name PARTITION (dt='2021-08-08') SET LOCATION "new location";
ALTER TABLE table_name PARTITION (dt='2021-08-08') RENAME TO PARTITION (dt='20210808');


1.7 添加分区

添加分区命令:

hive>alter table tmp_table add partition(dt="2021-12-01", hotel= "AAA");

插入数据命令:

hive>insert into tmp_table partition(dt="2021-12-01", hotel= "AAA") values('test_001', 100);


1.8 删除分区

命令:

ALTER TABLE tmp_table DROP IF EXISTS PARTITION (dt="2021-12-01", hotel= "AAA");


小结:

  1. Hive 的分区相当于按文件夹对文件进行分类存储,文件夹名可类比成分区字段名。
  2. 分区字段形式上存在于数据表中,在查询时会显示到客户端上,但并不真正的存储在数据表文件中,是所谓伪列
  3. 因此,千万不要以为是对属性表中真正存在的列按照属性值的异同进行分区
  4. 比如上面的分区依据的列 year 和 month 并不真正的存在于数据表 login_logs 中,是我们为了方便管理添加的一个伪列,这个列的值也是我们人为规定的,不是从数据表中读取之后根据值的不同将其分区。我们并不能按照某个数据表中真实存在的列,如 login_logs 表的字段 l_loginName 来分区。

相关推荐

Go语言泛型-泛型约束与实践(go1.7泛型)

来源:械说在Go语言中,Go泛型-泛型约束与实践部分主要探讨如何定义和使用泛型约束(Constraints),以及如何在实际开发中利用泛型进行更灵活的编程。以下是详细内容:一、什么是泛型约束?**泛型...

golang总结(golang实战教程)

基础部分Go语言有哪些优势?1简单易学:语法简洁,减少了代码的冗余。高效并发:内置强大的goroutine和channel,使并发编程更加高效且易于管理。内存管理:拥有自动垃圾回收机制,减少内...

Go 官宣:新版 Protobuf API(go pro版本)

原文作者:JoeTsai,DamienNeil和HerbieOng原文链接:https://blog.golang.org/a-new-go-api-for-protocol-buffer...

Golang开发的一些注意事项(一)(golang入门项目)

1.channel关闭后读的问题当channel关闭之后再去读取它,虽然不会引发panic,但会直接得到零值,而且ok的值为false。packagemainimport"...

golang 托盘菜单应用及打开系统默认浏览器

之前看到一个应用,用go语言编写,说是某某程序的windows图形化客户端,体验一下发现只是一个托盘,然后托盘菜单的控制面板功能直接打开本地浏览器访问程序启动的webserver网页完成gui相关功...

golang标准库每日一库之 io/ioutil

一、核心函数概览函数作用描述替代方案(Go1.16+)ioutil.ReadFile(filename)一次性读取整个文件内容(返回[]byte)os.ReadFileioutil.WriteFi...

文件类型更改器——GoLang 中的 CLI 工具

我是如何为一项琐碎的工作任务创建一个简单的工具的,你也可以上周我开始玩GoLang,它是一种由Google制作的类C编译语言,非常轻量和快速,事实上它经常在Techempower的基准测...

Go (Golang) 中的 Channels 简介(golang channel长度和容量)

这篇文章重点介绍Channels(通道)在Go中的工作方式,以及如何在代码中使用它们。在Go中,Channels是一种编程结构,它允许我们在代码的不同部分之间移动数据,通常来自不同的goro...

Golang引入泛型:Go将Interface「」替换为“Any”

现在Go将拥有泛型:Go将Interface{}替换为“Any”,这是一个类型别名:typeany=interface{}这会引入了泛型作好准备,实际上,带有泛型的Go1.18Beta...

一文带你看懂Golang最新特性(golang2.0特性)

作者:腾讯PCG代码委员会经过十余年的迭代,Go语言逐渐成为云计算时代主流的编程语言。下到云计算基础设施,上到微服务,越来越多的流行产品使用Go语言编写。可见其影响力已经非常强大。一、Go语言发展历史...

Go 每日一库之 java 转 go 遇到 Apollo?让 agollo 来平滑迁移

以下文章来源于GoOfficialBlog,作者GoOfficialBlogIntroductionagollo是Apollo的Golang客户端Apollo(阿波罗)是携程框架部门研...

Golang使用grpc详解(golang gcc)

gRPC是Google开源的一种高性能、跨语言的远程过程调用(RPC)框架,它使用ProtocolBuffers作为序列化工具,支持多种编程语言,如C++,Java,Python,Go等。gR...

Etcd服务注册与发现封装实现--golang

服务注册register.gopackageregisterimport("fmt""time"etcd3"github.com/cor...

Golang:将日志以Json格式输出到Kafka

在上一篇文章中我实现了一个支持Debug、Info、Error等多个级别的日志库,并将日志写到了磁盘文件中,代码比较简单,适合练手。有兴趣的可以通过这个链接前往:https://github.com/...

如何从 PHP 过渡到 Golang?(php转golang)

我是PHP开发者,转Go两个月了吧,记录一下使用Golang怎么一步步开发新项目。本着有坑填坑,有错改错的宗旨,从零开始,开始学习。因为我司没有专门的Golang大牛,所以我也只能一步步自己去...