0%

hive导入数据

hive数据导入全攻略:从 HDFS 到 INSERT 详解

Hive 作为数据仓库工具,数据导入是核心操作之一。由于 Hive 依赖 HDFS 存储数据,导入方式灵活多样,包括直接操作 HDFS、LOAD DATA 命令及 INSERT 语句。本文详细讲解每种导入方式的原理、操作步骤及注意事项,帮助开发者高效导入数据。

帮助开发者高效导入数据。

通过 HDFS 直接上传数据

Hive 表的数据本质上存储在 HDFS 目录中,因此可直接通过 HDFS 命令将数据文件上传到表对应的目录,实现数据导入。

操作步骤

  1. 创建表并确认存储路径
    先创建表(以内部表为例),并通过 desc formatted 查看表在 HDFS 上的存储路径:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    -- 创建表(指定列分隔符为制表符 \t)  
    create table if not exists dept(
    deptno int,
    dname string
    )
    row format delimited fields terminated by '\t';

    -- 查看表存储路径
    hive (study_hive)> desc formatted dept;
    ...
    Location: hdfs://localhost:9000/user/hive/warehouse/study_hive.db/dept
    ...
  2. 准备本地数据文件
    创建 dept.txt,内容如下(列之间用制表符分隔):

    1
    2
    1    财务  
    2 IT
  3. 通过 HDFS 命令上传文件
    使用 hdfs dfs -put 将本地文件上传到表的 HDFS 目录:

    1
    hdfs dfs -put ./dept.txt /user/hive/warehouse/study_hive.db/dept/  
  4. 查询表数据验证
    上传后直接查询表,数据已导入:

    1
    2
    3
    4
    5
    hive (study_hive)> select * from dept;  
    OK
    deptno dname
    1 财务
    2 IT

核心原理

  • Hive 表与 HDFS 目录一一对应,只要文件格式与表定义匹配(分隔符、列数一致),HDFS 目录中的文件会被 Hive 识别为表数据。
  • 此方式本质是 “物理文件迁移”,Hive 不参与数据处理,仅通过元数据关联文件。

元数据问题

通过 HDFS 直接上传的数据,Hive 元数据(如文件数、行数)不会自动更新:

1
2
3
4
5
6
7
8
9
-- 查询表元数据(numFiles、numRows 仍为 0)  
select PARAM_KEY, PARAM_VALUE from TABLE_PARAMS where TBL_ID = (select TBL_ID from TBLS where TBL_NAME = 'dept');
+----------------+-------------+
| PARAM_KEY | PARAM_VALUE |
+----------------+-------------+
| numFiles | 0 | -- 实际已有 1 个文件,但元数据未更新
| numRows | 0 | -- 实际已有 2 行数据
| totalSize | 0 |
+----------------+-------------+

原因:HDFS 上传操作未通知 Hive 元数据服务(Metastore),导致元数据与实际数据不一致。

使用 LOAD DATA 命令导入数据

LOAD DATA 是 Hive 官方推荐的导入方式,支持从本地文件系统或 HDFS 加载数据,会自动更新元数据。

语法格式

1
LOAD DATA [LOCAL] INPATH '数据路径' [OVERWRITE] INTO TABLE 表名 [PARTITION (分区列=值, ...)];  
  • LOCAL:可选,指定从本地文件系统加载(否则从 HDFS 加载);
  • OVERWRITE:可选,覆盖表中已有数据(默认追加);
  • PARTITION:可选,用于分区表的数据导入。

实操示例

从本地文件系统导入(LOCAL
1
2
-- 导入本地文件 dept1.txt 到 dept 表(追加数据)  
LOAD DATA LOCAL INPATH '/Users/zhanghe/Desktop/dept1.txt' INTO TABLE dept;
  • 本地文件路径为操作系统路径(如 /home/user/data/dept1.txt);
  • 导入后本地文件仍保留(Hive 会复制文件到 HDFS)。
从 HDFS 导入(无 LOCAL
1
2
3
4
5
-- 先将文件上传到 HDFS 临时目录  
hdfs dfs -put ./dept2.txt /tmp/

-- 从 HDFS 临时目录加载到表(移动文件,原路径文件会被删除)
LOAD DATA INPATH '/tmp/dept2.txt' INTO TABLE dept;
  • HDFS 路径为 HDFS 中的路径(如 /tmp/dept2.txt);
  • 导入后原 HDFS 文件会被 移动 到表目录(而非复制),原路径文件消失。

元数据更新验证

LOAD DATA 会自动更新元数据中的文件数、总大小等信息:

1
2
3
4
5
6
7
8
select PARAM_KEY, PARAM_VALUE from TABLE_PARAMS where TBL_ID = (select TBL_ID from TBLS where TBL_NAME = 'dept');  
+----------------+-------------+
| PARAM_KEY | PARAM_VALUE |
+----------------+-------------+
| numFiles | 2 | -- 包含 HDFS 上传的 1 个文件 + LOAD 的 1 个文件
| totalSize | 44 | -- 实际文件总大小
| numRows | 0 | -- 仍为 0,因未统计行数
+----------------+-------------+

为什么 numRows 仍为 0?
LOAD DATA 仅移动 / 复制文件,不扫描文件内容,因此无法获取行数(需通过 ANALYZE TABLE 手动统计)。

关键特性

  • 元数据同步:自动更新 numFilestotalSize 等元数据,比 HDFS 直接上传更可靠;
  • 操作本质
    • 本地文件:复制到表的 HDFS 目录;
    • HDFS 文件:移动到表的 HDFS 目录(原文件删除);
  • 适用场景:批量导入原始数据(如日志文件、CSV 文件),无需复杂转换。

使用 INSERT 语句插入数据

INSERT 语句通过 SQL 语法插入数据,支持从查询结果导入或直接指定值,适合动态生成数据。

语法格式

1
2
3
4
5
6
7
8
-- 追加数据  
INSERT INTO TABLE 表名 VALUES (值1, 值2, ...), (值3, 值4, ...);

-- 覆盖数据
INSERT OVERWRITE TABLE 表名 VALUES (值1, 值2, ...);

-- 从查询结果导入
INSERT INTO TABLE 目标表 SELECT1, 列2 FROM 源表 WHERE 条件;

实操示例

直接插入值
1
2
3
4
5
6
7
8
9
10
11
12
-- 追加两行数据  
INSERT INTO TABLE dept VALUES (201, '人事'), (202, '公关');

-- 查询结果
hive (study_hive)> select * from dept;
OK
1 财务
2 IT
1001 产品 -- 来自 HDFS 上传
1002 测试 -- 来自 LOAD DATA
201 人事 -- 来自 INSERT
202 公关 -- 来自 INSERT
从其他表导入
1
2
3
4
5
-- 创建临时表并插入数据  
CREATE TABLE IF NOT EXISTS dept_temp AS SELECT * FROM dept WHERE deptno > 100;

-- 将临时表数据导入 dept 表(覆盖)
INSERT OVERWRITE TABLE dept SELECT * FROM dept_temp;

核心原理

INSERT 语句会触发 MapReduce(或其他执行引擎)任务,将数据写入表的 HDFS 目录,同时更新元数据。与 LOAD DATA 相比:

  • LOAD DATA 仅移动 / 复制文件,不处理数据
  • INSERT 可对数据进行过滤、转换(通过 SELECT 子句),支持复杂数据处理

注意事项

  • 性能问题INSERT 触发计算任务,小数据量导入效率低于 LOAD DATA
  • 文件格式:插入的数据会按表定义的存储格式(如 TEXTFILEPARQUET)写入;
  • 元数据更新numRows 仍需手动统计(ANALYZE TABLE dept COMPUTE STATISTICS;)。

常见问题解答

1. 为什么 HDFS 上传的文件会被 LOAD DATA 统计?

Hive 表的 HDFS 目录下的所有文件都会被视为表数据,无论导入方式(HDFS 上传或 LOAD DATA)。LOAD DATA 会扫描表目录,将实际文件数更新到元数据,因此之前通过 HDFS 上传的文件会被计入 numFiles

2. 如何更新元数据中的行数(numRows)?

通过 ANALYZE TABLE 命令手动统计数据量,更新元数据:

1
2
3
4
5
6
7
8
9
10
-- 统计表的行数和文件大小  
ANALYZE TABLE dept COMPUTE STATISTICS;

-- 验证元数据
select PARAM_KEY, PARAM_VALUE from TABLE_PARAMS where TBL_ID = (select TBL_ID from TBLS where TBL_NAME = 'dept');
+----------------+-------------+
| PARAM_KEY | PARAM_VALUE |
| numRows | 6 | -- 已更新为实际行数
| totalSize | 120 |
+----------------+-------------+

3. 三种导入方式的对比

导入方式 数据来源 元数据更新 适用场景 性能
HDFS 直接上传 HDFS / 本地 → HDFS 表目录 不更新 快速导入测试数据 高(无额外处理)
LOAD DATA 本地 / HDFS → 表目录 更新文件数、大小 批量导入原始数据 中(仅移动 / 复制文件)
INSERT 语句 SQL 查询结果 / 值 需手动统计行数 数据转换后导入 低(触发计算任务)

欢迎关注我的其它发布渠道