Hive-DML:Load-Insert-Export-Import四种数据进出方式

Hive:DML 数据操作------Load、Insert、Export、Import 四种数据进出方式

Hive数据进出有四种方式:LOAD DATA(本地复制、HDFS剪切)用于批量加载文件;INSERT SELECT实现表间结果集迁移,支持追加或覆盖;INSERT VALUES可手动插入单行,但生产慎用;INSERT DIRECTORY将查询结果导出至本地或HDFS文件系统;EXPORT/IMPORT则支持整表连同元数据的跨集群迁移。其中,LOAD最高效,INSERT适用于加工逻辑,EXPORT/IMPORT适合表级迁移。核心原则:能用LOAD就不用INSERT,数据操作以文件和批量为主。

目录

  • 一、先想清楚:为什么 Hive 灌数据和 MySQL 不一样
  • 二、方式一:LOAD DATA 加载文件(最常用)
  • 三、方式二:INSERT 把查询结果插入表
  • 四、方式三:INSERT VALUES 直接插值
  • 五、方式四:查询结果导出到文件系统
  • 六、EXPORT / IMPORT:带元数据的导入导出
  • 七、四种方式对比总结

一、先想清楚:为什么 Hive 灌数据和 MySQL 不一样

在 MySQL 里你习惯了随时 insert into ... values(...) 单条插、update 单条改。到 Hive 里请先换个思维:

Hive 是面向批量分析的数仓工具,不是事务数据库。 数据进出的主角是"文件"和"批量结果集",而不是"单行记录"。

所以 Hive 的 DML 围绕四个问题展开:

  1. 本地/集群的文件怎么整批装进表?→ LOAD DATA
  2. 一张表的查询结果怎么存进另一张表?→ INSERT SELECT
  3. 表里的数据怎么导出成文件?→ INSERT DIRECTORY / EXPORT
  4. 整张表连结构带数据怎么搬家?→ EXPORT / IMPORT

下面逐一实操。统一使用 students 表:

sql 复制代码
create table if not exists bigdata.students1(
  id string comment '学号',
  name string comment '姓名',
  age int comment '年龄',
  sex string comment '性别',
  clazz string comment '班级'
)
row format delimited fields terminated by ',';

二、方式一:LOAD DATA 加载文件(最常用)

2.1 语法

sql 复制代码
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename 
[PARTITION (partcol1=val1, ...)]

三个可选零件,每个都是考点:

零件 不写 / 写了 的区别
LOCAL 写 :从 Linux 本地路径加载;不写:从 HDFS 路径加载
OVERWRITE 写 :清空表里原有数据再装;不写:追加到表尾
PARTITION 分区表指定装到哪个分区(第 4 篇展开)

2.2 加载本地文件:复制

sql 复制代码
load data local inpath '/root/sh_code/student.csv' overwrite into table students1;

查询验证:

sql 复制代码
select * from students1 limit 3;

输出:

复制代码
OK
id          name    age  sex  clazz
1500100001  施笑槐   22   男   理科一班
1500100002  吕梓杨   24   男   理科二班
1500100003  张三     21   女   理科一班
Time taken: 2.104 seconds, Fetched: 3 row(s)

本质:把本地文件复制一份到表的 HDFS 目录下。 本地原文件还在。

2.3 加载 HDFS 文件:剪切!

先准备一张同结构的空表,把文件先传到 HDFS:

shell 复制代码
hdfs dfs -put student.csv /student.csv
sql 复制代码
create table if not exists bigdata.students2 like students1;

load data inpath '/student.csv' overwrite into table students2;

再查一下 HDFS 根目录:

shell 复制代码
hdfs dfs -ls /
复制代码
Found 3 items
-rw-r--r--   ...  /students5     (其他文件)
drwxr-xr-x   ...  /data
# /student.csv 不见了!它被"移动"进了 students2 的表目录

核心区别(面试可考):

来源 行为 原文件
load data local 复制到表目录 还在
load data (hdfs) 移动到表目录 消失(相当于 mv)

口诀:本地复制,HDFS 剪切。 道理很简单:数据都已经在 HDFS 上了,再复制一份纯属浪费存储,挪个目录就完事。

2.4 OVERWRITE 追加实验

不加 OVERWRITE 就是追加。连续执行两次加载(去掉 overwrite):

sql 复制代码
load data local inpath '/root/sh_code/student.csv' into table students1;
load data local inpath '/root/sh_code/student.csv' into table students1;
sql 复制代码
select count(1) from students1;
复制代码
OK
_c0
1000        (假设原文件1000行,现在翻倍了)

生产建议:写脚本重复执行时,先想清楚要"追加"还是"覆盖",用错 OVERWRITE 会把辛苦算好的数据清掉,用错追加会数据翻倍。

三、方式二:INSERT 把查询结果插入表

3.1 INSERT INTO vs INSERT OVERWRITE

sql 复制代码
-- into:追加写入
insert into table students5 select * from students1;

-- overwrite:清空目标表再写入
insert OVERWRITE table students5 select * from students1;

典型场景:宽表加工。比如从学生明细表算出一张"每班人数汇总表":

sql 复制代码
insert overwrite table clazz_count
select clazz, count(1) as num
from students1
group by clazz;

这个"查询结果落成一张新表"的模式,就是数仓分层(ODS → DWD → DWS)最基础的动作。

3.2 性能提醒

insert ... select 底层是一个 MapReduce 任务,比 load 慢得多。原则:能 load 不 insert;表到表的加工才用 insert。

四、方式三:INSERT VALUES 直接插值

sql 复制代码
insert into table students5 VALUES('100001','张三',25,'1','文科一班');

能跑,但生产上基本不用:

  • 插一条数据也要起一个 MR 任务,秒级变分钟级
  • 数仓的数据来源是批量文件或上游表,不存在"手工逐行插"

了解即可,别养成习惯。

五、方式四:查询结果导出到文件系统

5.1 单路导出

sql 复制代码
INSERT OVERWRITE [LOCAL] DIRECTORY directory1
  [ROW FORMAT row_format] [STORED AS file_format]
  SELECT ... FROM ...;

案例:把表数据导出到 Linux 本地目录,逗号分隔:

sql 复制代码
insert overwrite local directory '/root/students5' 
row format delimited fields terminated by ','
select * from students5;

查看结果:

shell 复制代码
cat /root/students5/000000_0 | head -3
复制代码
1500100001,施笑槐,22,男,理科一班
1500100002,吕梓杨,24,男,理科二班
1500100003,张三,21,女,理科一班

几个细节:

  • 不写 LOCAL 就是导到 HDFS 目录
  • 结果文件名固定形如 000000_0,有几个 Reduce 就有几个文件
  • row format ... terminated by ',' 决定导出文件的分隔符,不写默认是控制符 \001,打开会全是乱码

5.2 多路导出(Multiple Inserts)

一次查询结果可以同时导到多个地方,语法是从 FROM 开头:

sql 复制代码
FROM students5
INSERT OVERWRITE LOCAL DIRECTORY '/root/out_male'
SELECT * WHERE sex = '男'
INSERT OVERWRITE LOCAL DIRECTORY '/root/out_female'
SELECT * WHERE sex = '女';

一次扫描、多份输出,省了重复读表的开销。

六、EXPORT / IMPORT:带元数据的导入导出

前面四种方式只搬"数据",EXPORT/IMPORT 连元数据 (表结构等)一起打包,常用于集群间整表迁移。

6.1 导出

sql 复制代码
EXPORT TABLE students5 TO '/students5';

6.2 导入

先把目标表清空(模拟"换个集群的空表"):

sql 复制代码
truncate table students1;

import table students1 from '/students5';

验证:

sql 复制代码
select count(1) from students1;
复制代码
OK
_c0
1000

数据回来了。注意 EXPORT/IMPORT 走的是 HDFS 路径,迁移跨集群时通常配合 distcp 把导出目录拷到目标集群再 IMPORT。

七、四种方式对比总结

方式 方向 数据粒度 是否动元数据 典型场景
LOAD DATA(local) 文件 → 表 整个文件 否 灌原始数据,最快
LOAD DATA(hdfs) 文件 → 表 整个文件 否 HDFS 上已有文件挂到表(剪切)
INSERT SELECT 表 → 表 结果集 否 数仓分层加工
INSERT VALUES 手工 → 表 单行 否 测试玩玩,生产不用
INSERT DIRECTORY 表 → 文件 结果集 否 导出分析结果
EXPORT / IMPORT 表 ↔ HDFS 目录 整表 是(连结构) 跨集群整表迁移

一句话收尾 :日常数据处理 90% 只用两个动作------load 灌数、insert ... select 加工;剩下四个了解即可,面试和救急时能想起来就行。


相关推荐
加百力1 小时前
沪指险守3700点,券商、银行午后发力,创业板跌近3%,半导体尾盘反扑,恒科指跌3%,科网股普跌
大数据
eBest数字化转型方案2 小时前
快消渠道 AI 落地路线:拍照、数据、决策三阶段的工程逻辑
大数据·人工智能
百胜软件@百胜软件2 小时前
百胜软件黄飞:让AI真正走进零售,把不确定性变成“胜券在握”
大数据·人工智能·零售
4SAPI2 小时前
官方API、API聚合平台与自建LLM Gateway:三种方案怎么选
大数据·人工智能·gateway·php
ManageEngineITSM2 小时前
工单优先级怎么定?影响×紧急度矩阵的设计与落地方法
java·大数据·运维·前端·数据库·变更管理
智商网输送线配件3 小时前
电子制造零散耗材补货实战:小批量混批采购平台怎么选才不停机?
大数据·服务器·前端·数据库·自动化
程序员IT行业3 小时前
广东行政事业单位物资管理系统选型:先定功能需求,再定部署架构
大数据·架构
橙色云-智橙协同研发3 小时前
汽车零部件行业:如何应对主机厂的严苛审核?
大数据·运维·服务器·人工智能·安全
努力变大白3 小时前
把“会说话的模型“变成“会干活的 Agent“
大数据·人工智能·机器学习