我正在编写一个自定义 Hive SerDe,它可以读取存储为 ORC 的数据。
基础表包含一个 event_map 列 MAP。SerDe 从 event_map 列读取数据,并在经过一些额外处理后将它们分解为单独的列。例如:地图将是 {'key1': 'val1', 'key2': 'val2'}。
然后我将创建一个外部表,如:
ADD JAR hdfs:///user/my-serde.jar;
CREATE EXTERNAL TABLE IF NOT EXISTS dev_db.expand_data_using_serde (
key1 STRING,
key2 STRING
) PARTITIONED BY (
ds STRING
)
ROW FORMAT SERDE 'com.....MySerDeClass'
WITH SERDEPROPERTIES (
"key1" = "extract_json",
"key2" = "multiply_by_5"
)
STORED AS ORC
LOCATION 'hdfs://dev.db/underlying_table_stored_as_orc';
USE dev_db;
MSCK REPAIR TABLE expand_data_using_serde;
然后,SerDe 会找到“key1”和“key2”列,并将其从底层映射中提取出来,并将它们作为单独的列而不是 MAP 公开。我知道我们可以通过配置单元查询来扩展此列,但为简单起见提供此示例。即 SerDe 将检查表 DDL 是否将 key1 作为列,并将从 event_map 中提取 key1 并将其用于该列。
大部分处理都在 serde 的 deserialize() 函数中。但是,我注意到我的 initialize() 方法被调用了 8 次。
这是为什么?每行调用一次反序列化,这是有道理的,但重复调用初始化。
此外,SerDe 可以通过“列”属性访问输出表模式,它也可以访问查询吗?
例如:如果我的查询是
SELECT key1 FROM dev_db.expand_data_using_serde;
serde 能知道我们只需要读取 key1 并跳过对 key2 的处理吗?