hive导出数据
Hive 数据导出:INSERT OVERWRITE、HDFS 下载、Shell 重定向、EXPORT,四种方式怎么选?
往 Hive 外面导数据,有四种方式:
| 方式 | 数据去哪 | 格式可控 | 含元数据 | 适用场景 |
|---|---|---|---|---|
| INSERT OVERWRITE LOCAL | 本地文件系统 | 可指定分隔符 | 不含 | 导出给 Excel/MySQL 等工具用 |
| INSERT OVERWRITE HDFS | HDFS 目录 | 可指定分隔符 | 不含 | 集群内数据共享 |
| Hive Shell 重定向(-e / -f) | 本地文件 | 默认制表符 | 不含 | 脚本化导出、定时任务 |
| EXPORT | HDFS 目录 | 固定格式 | 含 | 表迁移、备份恢复 |
方式1:INSERT OVERWRITE LOCAL——导出到本地,格式可控
这是最常用的导出方式,把查询结果导出到客户端机器的本地目录,可以指定分隔符。
语法:
INSERT OVERWRITE LOCAL DIRECTORY '/本地路径'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t' -- 指定分隔符
SELECT * FROM dept;
实操:
-- 导出到 /tmp/hive_export,用逗号分隔(CSV 格式)
INSERT OVERWRITE LOCAL DIRECTORY '/tmp/hive_export'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
SELECT deptno, dname FROM dept;
验证:
ls /tmp/hive_export/
000000_0 ← Hive 生成的文件
cat /tmp/hive_export/000000_0
1,财务
2,IT
特点:
- 可以指定分隔符(CSV、TSV、自定义)
- 导出到运行 Hive 的那台机器上
- 会触发 MapReduce/Tez 任务(小数据也慢)
什么时候用: 导出结果给 Excel、报表工具、其他系统用。
方式2:INSERT OVERWRITE HDFS——导出到 HDFS,集群内共享
跟方式1一样,只是导出到 HDFS 而不是本地。
语法:
INSERT OVERWRITE DIRECTORY '/hdfs路径'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
SELECT * FROM dept;
特点:
- 数据留在 HDFS 上,其他集群内工具可以直接读
- 同样可以指定分隔符
- 同样触发计算任务
什么时候用: 导出结果给 Spark、Flink 等其他引擎读,或者做数据交换。
方式3:Hive Shell 重定向——脚本化导出,适合定时任务
不进入 Hive 交互模式,在命令行直接执行 SQL 并把结果重定向到文件。
单条 SQL(-e):
hive -e "SELECT deptno, dname FROM study_hive.dept;" > /tmp/dept.txt
多条 SQL 用脚本(-f):
写一个 SQL 文件
echo "SELECT deptno, dname FROM study_hive.dept WHERE deptno > 100;" > query.sql
执行并导出
hive -f query.sql > /tmp/dept_filtered.txt
去掉日志干扰(-S 静默模式):
hive -S -e "SELECT * FROM dept;" > /tmp/dept_clean.txt
特点:
- 适合定时任务(crontab + hive -e)
- 默认分隔符是制表符(
\t) - 结果文件就是纯文本,没有表头
什么时候用: 每天定时导出报表、数据同步脚本。
方式4:EXPORT——带元数据导出,用于备份和迁移
EXPORT 不光导数据,还导表结构——相当于把整张表”打包”。
导出:
EXPORT TABLE study_hive.dept TO '/user/hive/export/dept';
导出后在 HDFS 上看到两个东西:
hdfs dfs -ls /user/hive/export/dept/
_metadata ← 表结构元数据
data ← 实际数据
导入(IMPORT):
IMPORT TABLE study_hive.dept_restore
FROM '/user/hive/export/dept';
特点:
- 导出包含元数据,导入时自动建表
- 不能指定分隔符(固定格式)
- 只支持整表导出(不能
WHERE过滤)
什么时候用: 表级备份、集群间迁移、跨环境同步。
一个关键坑:列式存储导出来是二进制
如果表用的是 Parquet、ORC 这种列式存储,INSERT OVERWRITE 导出的文件是二进制格式——cat 出来是乱码。
-- 表是 ORC 格式
CREATE TABLE dept_orc STORED AS ORC AS SELECT * FROM dept;
-- 直接导出
INSERT OVERWRITE LOCAL DIRECTORY '/tmp/dept_export'
SELECT * FROM dept_orc;
cat /tmp/dept_export/000000_0
# 乱码 ── 因为 ORC 是二进制格式
解决方案:
导出时转换成文本格式:
INSERT OVERWRITE LOCAL DIRECTORY '/tmp/dept_export'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
SELECT * FROM dept_orc; -- 读 ORC,写文本,自动转了
或者先建一张文本格式的临时表,导进去再导出。