hive内部表和外部表

Hive 内部表 vs 外部表:建表之前,先想清楚”这数据归谁管”

Hive 建表的时候,有一个绕不开的选择:

  • 内部表(MANAGED_TABLE):Hive 管数据,删表删数据
  • 外部表(EXTERNAL_TABLE):用户管数据,删表不删数据

怎么选?先回答一个问题:这份数据,Hive 是”独家拥有”还是”借来用用”?

数据来源 选什么
Flume 采集的日志、其他系统产生的原始数据 外部表(数据是别人的,Hive 只是借来查)
Hive ETL 生成的中间表、临时表、结果表 内部表(数据是 Hive 自己产生的,删了没关系)

内部表:Hive 管数据,删表就删数据

内部表是 Hive 的默认表类型。建表时不加 EXTERNAL,就是内部表。

建表语法:

CREATE TABLE user_info (
  id INT,
  name STRING,
  age INT
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

数据存哪? 默认在 /user/hive/warehouse/ 下,按库名和表名组织:

/user/hive/warehouse/study_hive.db/user_info/

删表时发生什么?

DROP TABLE user_info;
  • 元数据(表结构)被删
  • HDFS 上的数据文件也被删

什么时候用内部表?

  • ETL 过程中的中间表(算完就扔)
  • 临时表(测试用,用完就删)
  • Hive 自己产生的数据(不跟其他系统共享)

外部表:用户管数据,删表不删数据

外部表的数据存在 Hive 以外的地方,Hive 只是”借来查一下”。

建表语法(多了 EXTERNALLOCATION):

CREATE EXTERNAL TABLE log_data (
  ip STRING,
  access_time STRING,
  url STRING
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' '
LOCATION '/data/nginx/logs/2026-07-20';

数据存哪? 建表时通过 LOCATION 指定,数据已经在那个路径下了。

删表时发生什么?

DROP TABLE log_data;
  • 元数据(表结构)被删
  • HDFS 上的数据文件还在

什么时候用外部表?

  • 日志数据(Flume 采集的原始数据)
  • 跟 Spark、Flink 等共享的数据
  • 长期保留的原始数据(删表不能删数据)

内部表 vs 外部表:一张表看清楚

对比项 内部表 外部表
创建关键字 不加 EXTERNAL 必须加 EXTERNAL
数据路径 默认 warehouse 目录 LOCATION 指定
删表时 删元数据 + 删数据 只删元数据,数据不动
数据谁管 Hive 管 用户管
典型场景 Hive 产生的中间数据 外部系统产生的原始数据
风险 删表误删数据 表删了数据还在,元数据丢了

内表转外表 / 外表转内表

内部表 → 外部表:

ALTER TABLE user_info SET TBLPROPERTIES('EXTERNAL'='TRUE');

外部表 → 内部表:

ALTER TABLE log_data SET TBLPROPERTIES('EXTERNAL'='FALSE');

转换后怎么确认?

DESC FORMATTED user_info;
-- 看 Table Type:
-- MANAGED_TABLE = 内部表
-- EXTERNAL_TABLE = 外部表

什么场景需要转换?

  • 建表时选错了,发现删表会删数据 → 转为外部表保护数据
  • 数据不再需要共享,想统一管理 → 转为内部表

外部表的一个常见坑:元数据不自动同步

外部表的数据在 HDFS 上,Hive 只记录元数据。如果有人在 HDFS 上直接新增/删除/移动了数据文件,Hive 不知道。

现象:LOCATION 目录下新增了一个分区目录,SHOW PARTITIONS 看不到。

解决: 刷新元数据

MSCK REPAIR TABLE log_data;

这条命令会扫描 LOCATION 目录,把新增的分区同步到元数据里。