向hive中加载或添加数据的三种方式

本文介绍了向Hive中加载数据的三种方式:load数据、insert插入和create...as操作。通过实例展示了如何对普通表和分区表进行数据加载,包括静态与动态分区的使用,以及如何复制分区表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

每次博客尽量以一个项目的标准来写,做到大家可以动手操作实践。

首先准备数据源:学生成绩txt文件,共七个字段(ID,name,Chinese,English,math,school,class)

[root@xxx tmp]#  hdfs dfs -cat  /tmp/score.txt 
0001,zhangsan,99,98,100,school1,class1
0002,lisi,59,89,79,school2,class1
0003,wangwu,89,99,100,school3,class1
0004,zhangsan2,99,98,100,school1,class1
0005,lisi2,59,89,79,school2,class1
0006,wangwu2,89,99,100,school3,class1

 

建普通表:
create table score1
(id string comment 'ID', 
name string comment 'name',  
Chinese double comment 'Chinese',
English double comment 'English',
math double comment 'math',
school string comment 'school',
class string comment 'class')
comment 'score1'  
row format delimited fields terminated by ','
stored as textfile;

 

建分区表语句:

create table score
(id string comment 'ID', 
name string comment 'name',  
Chinese double comment 'Chinese',
English double comment 'English',
math double comment 'math')
comment 'score'  
partitioned by(school string,class string)
row format delimited fields terminated by ','

stored as textfile;

 

一、load加载

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]  

解释:
local:可选,表示从本地文件系统中加载,而非hdfs
overwrite:可选,先删除原来数据,然后再加载

partition:这里是指将inpath中的所有数据加载到那个分区,并不会判断待加载的数据中每一条记录属于哪个分区。

注意:load完了之后,会自动把INPATH下面的源数据删掉,其实就是将INPATH下面的数据移动到/usr/hive/warehouse目录下了。

分区加载:load data inpath '/tmp/score.txt' into table score partition (school="school1",class="class1") 

select * from score查询出来的六条记录,两个分区字段都变成了school1和class1

 

 score.idscore.namescore.chinesescore.englishscore.mathscore.schoolscore.class
10001zhangsan9998100school1class1
20002lisi598979school1class1
30003wangwu8999100school1class1
40004zhangsan29998100school1class1
50005lisi2598979school1class1
60006wangwu28999100school1class1


而hive的score表对应的hdfs文件依旧没变,因此load的命令的执行其实就是简单的mv操作。
[root@xxx tmp]#  hdfs dfs -cat /user/hive/warehouse/jira.db/score/school=school1/class=class1/score.txt
0001,zhangsan,99,98,100,school1,class1
0002,lisi,59,89,79,school2,class1
0003,wangwu,89,99,100,school3,class1
0004,zhangsan2,99,98,100,school1,class1
0005,lisi2,59,89,79,school2,class1

0006,wangwu2,89,99,100,school3,class1

如果要实现真正的分区加载则应该采用下面的加载方式。

先load加载到非分区表score1:

load data inpath '/tmp/score.txt' into table score1;

这个时候查询是ok的

 score1.idscore1.namescore1.chinesescore1.englishscore1.mathscore1.schoolscore1.class
10001zhangsan9998100school1class1
20002lisi598979school2class1
30003wangwu8999100school3class1
40004zhangsan29998100school1class1
50005lisi2598979school2class1
60006wangwu28999100school3class1

再insert into 到分区表,见下面操作。

二、insert插入

hive不支持INSERT INTO, UPDATE, DELETE操作,这样的话,就不要很复杂的锁机制来读写数据。
INSERT INTO syntax is only available starting in version 0.8。INSERT INTO就是在表或分区中追加数据,并不是经典数据库中的insert into操作,只是insert into单词一样。

基本模式
INSERT INTO|OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1
多插入模式
FROM frometable1,fromtable2....
INSERT INTO|OVERWRITE TABLE desttable1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1
[INSERT INTO|OVERWRITE TABLE desttable2 [PARTITION ...] select_statement2] ...
动态分区模式

INSERT INTO|OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement

 

将score1中的某个分区数据insert到score中:
insert overwrite table score partition (school="school1",class="class1") select id,name,Chinese,English,math from score1 where school="school1" and class="class1";
insert overwrite table score partition (school="school2",class="class1") select id,name,Chinese,English,math from score1 where school="school2" and class="class1";

insert overwrite table score partition (school="school3",class="class1") select id,name,Chinese,English,math from score1 where school="school3" and class="class1";

查询表文件数据:
[root@xxx tmp]#  hdfs dfs -cat  /user/hive/warehouse/jira.db/score/school=school1/class=class1/000000_0
0001,zhangsan,99.0,98.0,100.0

0004,zhangsan2,99.0,98.0,100.0

分区数据并没有存在表文件中,仅存在目录上,因此,这下hive的分区本质摸清楚了。那么问题来了,假如分区数很多,每条一个分区岂不累死,hive提出了动态分区的功能,上面的语句是静态分区,需要手动指定。动态分区和静态分区并不在我们这章博客的讨论范围。

 

三、create ... as操作

这个相对简单
create table score2 as select * from score
建完的score2表没有分区,因此,create ... as 不能复制分区表。

分区表的复制:
1.需要先用create table score3 like score来复制表结构,然后将原表的数据复制到 新表(score3)
1. 创建新表: create table score3 like score;
2. 将HDFS的数据文件复制一份到新表目录,hive cmd模式下: 
dfs -cp -f /user/hive/warehouse/score/* /user/hive/warehouse/score3/
3. 修复分区元数据信息,hive cmd模式下: MSCK REPAIR TABLE score3;


 

 

 

 

 

### 创建Hive表并加载现有数据Hive中创建新表并将现有数据加载到该表的过程涉及多个步骤。具体操作取决于所要创建的是托管表还是外部表。 对于托管表,在创建之后,可以通过`LOAD DATA`语句来移动本地文件系统中的数据至HDFS上的指定位置: ```sql CREATE TABLE managed_table(id INT, name STRING); LOAD DATA LOCAL INPATH '/path/to/local/file' INTO TABLE managed_table; ``` 上述命令会将位于本地路径下的文件内容载入名为`managed_table`的新建托管表中[^1]。 而对于外部表,则允许指向已经存在于HDFS其他支持的数据源内的数据集而不必复制这些数据;这使得删除表格时仅移除元数据而非实际数据本身: ```sql CREATE EXTERNAL TABLE external_table(id INT, name STRING) LOCATION '/path/in/hdfs/'; ``` 当处理来自其他系统的已有数据时,还可以利用诸如Sqoop这样的工具先将关系型数据库管理系统(RDBMS)里的数据导出成文本格式再上传至目标目录,最后通过类似下面的指令完成加载过程: ```sql LOAD DATA INPATH '/tmp/sqoop_exported_data' INTO TABLE external_table; ``` 另外,针对更复杂的情况更大规模的数据迁移需求,可以考虑采用Hive与HBase集成的方式来实现高效的数据导入。这种方式特别适合于那些希望保持键值对结构不变的应用场景。例如: ```sql CREATE TABLE hbase_imported_table(rowkey STRING, column_family_x INT, column_family_y INT) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf:x,cf:y"); INSERT OVERWRITE TABLE hbase_imported_table SELECT * FROM source_hive_table; ``` 此方法不仅能够快速地把大量记录迁移到分布式环境中,而且还能充分利用两者各自的优势特性[^2]。 #### 错误处理建议 值得注意的是,在执行任何涉及到大规模数据传输的任务之前,请务必确认所有必要的配置参数都已正确设置,并仔细阅读相关文档以避免潜在错误的发生。如果遇到类似于“return code 40000”的异常情况,通常情况下简单的重试即可解决问题。然而为了从根本上找出原因并防止未来再次发生相同的问题,深入研究日志信息以及查看对应的Java堆栈跟踪是非常有帮助的做法[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值