Hive 分区 是如何在元数据(MySQL)存储的?

24 阅读4分钟

1.将元数据存到MySql,建了分区之后,如何获取元数据。

1.Hive端建表与添加分区

-- 创建分区表 
CREATE TABLE doc_test_partition 
(   
   user_id INT, 
   amount DOUBLE 
) 
PARTITIONED BY (dt STRING) 
STORED AS TEXTFILE; 
-- 添加分区(触发元数据写入) 
ALTER TABLE doc_test_partition ADD PARTITION (dt='2026-03-26');
  1. MySQL端查询元数据
USE hive_metastore; 

SELECT 
t.TBL_NAME AS '表名', 
p.PART_NAME AS '分区路径名', 
s.LOCATION AS '存储路径', 
FROM_UNIXTIME(p.CREATE_TIME) AS '创建时间' 
FROM PARTITIONS p 
JOIN TBLS t ON p.TBL_ID = t.TBL_ID 
JOIN SDS s ON p.SD_ID = s.SD_ID 
WHERE t.TBL_NAME = 'doc_test_partition';

查询结果

表名分区路径名存储路径创建时间
doc_test_partitiondt=2026-03-26file:/tmp/hive-warehouse/doc_test_partition/dt=2026-03-262026-03-27 02:29:22

结论

  1. 存储机制:Hive分区元数据存储在hive_metastore库的PARTITIONS表中,PART_NAME字段记录分区路径(如dt=2026-03-26),物理路径通过SDS表关联获取。
  2. 获取方式:可直接查询MySQL元数据库获取分区信息,或通过Hive命令SHOW PARTITIONS doc_test_partition;间接获取。

2.一个表下面建多个分区,比如粒度到 月、天、小时,元数据的情况。

1.Hive端建表与添加分区

-- 创建包含 年、月、日、时 四级分区的表
CREATE TABLE doc_test_multi_part (
    user_id INT,
    amount DOUBLE
)
PARTITIONED BY (year_str STRING, month_str STRING, day_str STRING, hour_str STRING)
STORED AS TEXTFILE;

-- 添加一个具体的多级分区
ALTER TABLE doc_test_multi_part 
ADD PARTITION (year_str='2026', month_str='03', day_str='27', hour_str='10');

2.MySQL端查询元数据

USE hive_metastore; 
SELECT 
    t.TBL_NAME AS '表名', 
    p.PART_NAME AS '分区路径名', 
    s.LOCATION AS '存储路径', 
    FROM_UNIXTIME(p.CREATE_TIME) AS '创建时间' 
FROM PARTITIONS p 
JOIN TBLS t ON p.TBL_ID = t.TBL_ID 
JOIN SDS s ON p.SD_ID = s.SD_ID 
WHERE t.TBL_NAME = 'doc_test_multi_part';
表名分区路径名存储路径创建时间
doc_test_multi_partyear_str=2026/month_str=03/day_str=27/hour_str=10file:/tmp/hive-warehouse/doc_test_multi_part/year_str=2026/month_str=03/day_str=27/hour_str=102026-03-27 02:52:04

结论

1.存储结构:多级分区在元数据库中依然存储为单层字符串,而非嵌套结构。

2. 拼接规则:不同层级的分区字段通过斜杠 / 连接,格式为 字段1=值1/字段2=值2/...

3. 物理映射:该字符串直接对应 HDFS 上的嵌套文件夹路径,Hive 通过解析该路径实现多级目录定位。

3.建不同名字的分区字段、或者不同格式的分区值,比如按天分区,可以是tday或者day, 值可能是 2026-03-25或者 20260325

1.Hive端建表与添加分区

-- 表A:tday字段,标准日期格式 
CREATE TABLE doc_test_format_a ( 
    user_id INT 
) 
PARTITIONED BY (tday STRING)
STORED AS TEXTFILE; 
ALTER TABLE doc_test_format_a ADD PARTITION (tday='2026-03-25'); 
-- 表B:day字段,数字日期格式 
CREATE TABLE doc_test_format_b (
    user_id INT 
) 
PARTITIONED BY (day STRING) 
STORED AS TEXTFILE; 
ALTER TABLE doc_test_format_b ADD PARTITION (day='20260325');

2.MySQL端查询元数据

USE hive_metastore; 

SELECT
    t.TBL_NAME AS '表名', 
    p.PART_NAME AS '分区路径名', 
    s.LOCATION AS '存储路径'
FROM PARTITIONS p 
JOIN TBLS t ON p.TBL_ID = t.TBL_ID 
JOIN SDS s ON p.SD_ID = s.SD_ID 
WHERE t.TBL_NAME IN ('doc_test_format_a', 'doc_test_format_b');
表名分区路径名存储路径
doc_test_format_atday=2026-03-25file:/tmp/hive-warehouse/doc_test_format_a/tday=2026-03-25
doc_test_format_bday=20260325file:/tmp/hive-warehouse/doc_test_format_b/day=20260325

结论

  1. 值格式自由:分区值可为标准日期格式或数字格式,Hive不进行格式校验
  2. 存储映射:分区定义直接映射为HDFS路径结构,保持用户定义的原始形态

4. 加了字段或减了字段,元数据信息比对出数据库的表有没有变化

1.执行步骤

第一步:创建初始表并查询元数据(变更前)

-- Hive执行
-- 1. 创建初始表,仅包含两个字段 
CREATE TABLE doc_test_schema_v1 ( 
    user_id INT, 
    amount DOUBLE 
) 
STORED AS TEXTFILE; 

-- MySQL执行
-- 2. 查询当前字段信息(变更前快照) 
USE hive_metastore; 
SELECT 
    c.INTEGER_IDX AS '字段顺序', 
    c.COLUMN_NAME AS '字段名', 
    c.TYPE_NAME AS '字段类型' 
FROM COLUMNS_V2 c 
JOIN SDS s ON c.CD_ID = s.CD_ID 
JOIN TBLS t ON s.SD_ID = t.SD_ID 
WHERE t.TBL_NAME = 'doc_test_schema_v1' 
ORDER BY c.INTEGER_IDX;
字段顺序字段名字段类型
0user_idint
1amountdouble

第二步:修改表结构并再次查询(变更后)


-- Hive执行
-- 3. 模拟业务变更:增加一个字段 
USE default; 
ALTER TABLE doc_test_schema_v1 ADD COLUMNS (new_col STRING); 

-- MySQL执行
-- 4. 再次查询字段信息(变更后快照) 
USE hive_metastore; 
SELECT 
    c.INTEGER_IDX AS '字段顺序', 
    c.COLUMN_NAME AS '字段名',
    c.TYPE_NAME AS '字段类型' 
FROM COLUMNS_V2 c 
JOIN SDS s ON c.CD_ID = s.CD_ID 
JOIN TBLS t ON s.SD_ID = t.SD_ID 
WHERE t.TBL_NAME = 'doc_test_schema_v1' 
ORDER BY c.INTEGER_IDX;
字段顺序字段名字段类型
0user_idint
1amountdouble
2new_colstring

结论

1.Hive 的元数据库(hive_metastore)能够实时记录表结构的变更。一旦执行 ALTER TABLE ... ADD COLUMNS,元数据表 COLUMNS_V2 会立即更新。