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 只是”借来查一下”。
建表语法(多了 EXTERNAL 和 LOCATION):
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 目录,把新增的分区同步到元数据里。