hive表管理

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

hive是基于hadoop的一个数据仓库工具,可以将结构化的数据文件映射成一张表,并提供类sql的查询功能

hive文档地址: cwiki.apache.org/confluence/…

hive表有以下两种类型的表

  • MANAGED_TABLE 内部表
  • EXTERNAL_TABLE 外部表

表的应用场景

MANAGED_TABLE

  • 又称内部表 完全由hive管理的表,数据和元数据全部由hive管理
  • 删除表时,表结构和数据都会删除

EXTERNAL_TABLE

  • 又称外部表 数据共享给hive外的应用所访问,如spark,flink
  • 数据保护,删除表时只删除表结构,数据还存在hdfs中

表创建

创建表,并指定行分隔符为逗号, 如果不配分隔符,默认给的一个SOH,然后数据都连在一块,没有办法进行后续分析了

create table  test7(id int,name string) row format delimited fields terminated by ',';

insert into test7 values(10001,"zhangsan")
复制代码

image.png

查看表结构

desc formatted test7;
复制代码

修改表名

新表名如果存在会报错

alter table test1 rename to test2;
复制代码

修改列信息

修改列名, 列名的类型不支持强制转化,只能向上升级,比如string不可以改成int等

#修改列名
alter table test2 change id new_id int;
#新增列
alter table test2 add columns(email string);
#修改列类型(如果修改的列不存在,就新增该列)
alter table test2 replace columns(id string,gender string)
复制代码

表类型修改

关键字区分大小写,必须为大写

将内部表修改为外部表

alter table table_name set tblproperties('EXTERNAL'='TRUE')
复制代码

将外部表修改为内部表

alter table table_name set tblproperties('EXTERNAL'='FALSE')
复制代码

数据操作

加载数据

创建表时加载数据,或建表之后,再将数据导入

数据内容需要符合表结构

load data加载数据
# 直接从hdfs加载数据hive,其实就是把dmp.txt 文件移动到hive目录中
load data inpath '/test/dmp.txt' into table test1;

#有local关键字,表示从本地上传到hdfs hive目录
load data local inpath '/root/dmp.txt' into table test1;
复制代码
从其它表中导入数据
insert into table test7 select * from test1;
复制代码
创建表时指定加载数据
create external table if not exists test10(id int,name string)
for format delimited fields terminated by '\t'
location '/test/data10.txt'
复制代码
创建表时从另外一张加载数据
create table test11 as select id,name from test12;
复制代码

导出数据

导出数据一般操作较少,加载数据较多

要导出时一般要根据查询条件,写到本地,因为导出就是导出全部

查询结果导出到本地
insert overwirte local directory '/tmp/test2.txt' select * from test2;
复制代码
查询结果格式化导出到本地 以空格分隔
insert overwirte local directory '/tmp/test2.txt' 
FOR FORMAT DELIMITED FIELDS TERMINATED BY '\t' 
select * from test2;
复制代码
将查询结果导到hdfs 以逗号分隔
insert overwirte  directory '/tmp/test2.txt' 
FOR FORMAT DELIMITED FIELDS TERMINATED BY ',' 
select * from test2;
复制代码
导入导出,数据迁移
export table default.test7 to '/user/hive/warehouse/export/test7'
import table default.test7 from '/user/hive/warehouse/export/test7'
复制代码

清空数据和删除表

#查看表类型
desc formatted table_name;

#清空表数据(内部有效,外部无效)
truncate table table_name;

#删除外部表数据
hadoop fs -rm -r -f  /user/hive/warehouse/test.db/talbe_name

#删除表 (内部表全将数据和表结构全部删除,外部表只会删除表结构)
drop table table_name

#删除分区 括号里面是分区名和值
alter table table_name drop partition(load_date='2019-01-01')
复制代码

分区表

分区表对应一个HDFS文件系统上的独立文件夹,hive分区就是分目录,将大量数据分成小的文件夹放到一个目录中

动态分区

动态分区的好处是,不需要每次写入数据再去增加一个分区,而是自动处理.假设按天分区,每天写入数据,事先都要进行分区,一但表的数量过多,这效率就真很低下

cwiki.apache.org/confluence/…

image.png

创建分区表

create table if not exists test5(name string) partitioned by(age int) row format delimited fields terminated by ' ' lines terminated by '\n';
复制代码

数据导入分区表必须先在Hive中执行下面两句语句(开启动态分区)

set hive.exec.dynamic.partition=true; 
set hive.exec.dynamic.partition.mode=nonstrict;
复制代码

导入数据到分区表分为静态分区和动态分区两种方式

#静态方式,指定分区,每个分区执行一条sql
insert into table test5 partition(age=25) select name from test6;
#动态方式,确定字段的顺序和类型一致,分区字段的类型必须一致
insert overwrite table test5 partition select name,age from test6;
复制代码

按天分区例子(静态分区)

#数据样例
---------txt1
10 ACCOUNTING 1700
20 RESEARCH   1800
---------txt2
30 SALES 1900
40 OPERATIONS 1700
---------txt3
50 TEST 2000
60 DEV  1900
复制代码
#创建分区表
create table dept_par(deptno int,dname string, loc string)
partitioned by (day string)
row format delimited fields terminated by '\t';

#加载数据
load data local inpath '/opt/dept1.txt' into table dept_par partition(day='20221-09-01');

#查询数据 单分区
select * from dept_par where day='2021-09-01';

#查询数据 多分区联合
select * from dept_par where day='2021-09-01'
union
select * from dept_par where day='2021-09-02'
union
select * from dept_par where day='2021-09-03';
----
select * from dept_par where day='2021-09-01' or day='2021-09-02' or day='2021-09-03';

#增加分区
alter table dept_par add partition(day='2021-09-04');

#删除分区
alter table dept_par drop partition(day='2021-09-04')

#查看分区表有多少分区
show partitions dept_par

#查看分区表结构
desc fromatted dept_par

#二级分区 多一层目录结构,将数据再次细分
create table dept_par2(deptno int,dname string, loc string)
partitioned by (day string,hour string)
row format delimited fields terminated by '\t';
复制代码