SerDe 与数据解析
SerDe(序列化与反序列化器)决定 Hive 建表时如何把文件内容解析成一行行记录:纯文本用 LazySimpleSerDe 配分隔符,单行 JSON 用 JsonSerDe,ORC 与 Parquet 用内置的列式 SerDe。建表字段与实际文件不匹配时,典型表现是整列返回 NULL 或解析报错,所以接新数据源要先抽样验证。
基本信息
| 文本文件 | LazySimpleSerDe 加分隔符 |
|---|---|
| JSON 文件 | JsonSerDe 或自定义实现 |
| 列式文件 | ORC / Parquet 内置 SerDe |
| 常见异常 | 整列 NULL 或解析报错 |
| 验证手段 | 抽样查询加非空计数 |
典型使用场景
- 接入新日志:先用少量样本建临时表验证字段能正确解析
- 多来源同结构数据:SerDe 不同的分开建表,避免一张表混用两种解析规则
- JSON 嵌套字段:决定是先落文本再解析,还是直接建 MAP/STRUCT
- 字段内含分隔符:改用多字符分隔或直接换 JSON、列式格式
- 排查全 NULL:核对字段名大小写、嵌套层级与文件实际结构
JSON 外部表
JSON 外部表
CREATE EXTERNAL TABLE ods_event_json (
event_id STRING,
user_id STRING,
props MAP<STRING,STRING>
)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
LOCATION '/warehouse/ods/event_json';
-- 抽样验证:统计总行数与非空行数,确认不是解析失败造成的全列 NULL
SELECT count(1) AS rows_total, count(user_id) AS rows_with_user FROM ods_event_json;常见 SerDe 与适用文件
| SerDe | 适用文件 | 典型问题 |
|---|---|---|
| LazySimpleSerDe | 分隔符文本 | 字段内含分隔符导致列错位 |
| JsonSerDe | 单行 JSON | 字段名大小写不一致返回 NULL |
| ORC / Parquet | 列式文件 | 文件结构与表定义版本不匹配 |
| OpenCSVSerde | 带引号 CSV | 分隔符与引号设置不匹配 |
JSON 嵌套很深的字段若在建表时直接解析,读取开销会长期存在;高频查询的表建议先落成扁平化文本或列式表,再在其上分析。
外部表 LOCATION 指向的目录混入结构不同的文件时,解析按文件逐个进行,会出现部分行正常、部分行全 NULL 的现象;排查时要按文件名分组统计,而不是整表看一个数字。
文本表的分隔符、空值表示与转义字符在建表时要一次写全,并把抽样结果记进表说明;后面接手的人往往只能从建表语句反推这些约定,写清楚能省掉大量对齐成本。