Hive的复杂数据类型
array 建表定义:array < string> 取值:arr[0] 如何通过sql构造array:array(),collect_set()
map 建表定义:map <string,int> 取值:map[‘key’] 如何通过sql构造map:map(key1,value1,key2,value2,…),str_to_map(text[,delimiter1,delimiter2])
struct 建表定义:struct < id:int,name:string> 取值:struct.id或者struct.name 如何通过sql构造struct:named_struct()
该商品维度表的平台属性和销售属性的字段存在多值属性问题,字段类型是复杂数据类型嵌套,即结构体数组。
CREATE EXTERNAL TABLE IF NOT EXISTS dim_sku_full
(
`id` STRING COMMENT 'sku_id',
`price` DECIMAL(16,2) COMMENT '商品价格',
`sku_name` STRING COMMENT '商品名称',
`sku_desc` STRING COMMENT '商品描述',
`weight` DECIMAL(16,2) COMMENT '重量',
`is_sale` BOOLEAN COMMENT '是否在售',
`spu_id` STRING COMMENT 'spu编号',
`spu_name` STRING COMMENT 'spu名称',
`category3_id` STRING COMMENT '三级分类id',
`category3_name` STRING COMMENT '三级分类名称',
`category2_id` STRING COMMENT '二级分类id',
`category2_name` STRING COMMENT '二级分类名称',
`category1_id` STRING COMMENT '一级分类id',
`category1_name` STRING COMMENT '一级分类名称',
`tm_id` STRING COMMENT '品牌id',
`tm_name` STRING COMMENT '品牌名称',
`sku_attr_values` ARRAY<STRUCT<attr_id:STRING,value_id:STRING,attr_name:STRING,value_name:STRING>>COMMENT '平台属性',
`sku_sale_attr_values` ARRAY<STRUCT<sale_attr_id:STRING,sale_attr_value_id:STRING,sale_attr_name:STRING,sale_attr_value_name:STRING>>COMMENT '销售属性',
`create_time` STRING COMMENT '创建时间'
)COMMENT '商品维度表'
PARTITIONED BY (`dt` STRING)
STORED AS ORC
LOCATION '/warehouse/gmall/dim/dim_sku_full/'
TBLPROPERTIES ('orc.compress' = 'snappy');
以平台属性为例,得到想要的结构体数组
SELECT sku_id,
collect_set(named_struct('attr_id', attr_id, 'value_id', value_id, 'attr_name', attr_name, 'value_name',
value_name)) AS attrs
FROM ods_sku_attr_value_full
WHERE dt = '2020-06-14'
GROUP BY sku_id
该查询结果的每行代表一个sku的一个属性,但一个sku可以有多个属性。根据上述需求,现考虑使用named_struct()转成结构体,使用collect_set()聚合,将一个sku_id的多个struct结构体属性封装到一个结构体数组里。
多值属性问题:维表中的某个属性同时有多个值
解决方法: 第一种:将多值属性放到一个字段,该字段内容为key1:value1,key2:value2的形式。 第二种:将多值属性放到多个字段,每个字段对应一个属性。这种方案只适用于多值属性个数固定的情况。
上述例子为什么没有使用struct()和map(),以及为什么使用array(struct())的原因
未使用struct()原因:结构体字段不好确定,不同商品的平台属性key无法确定。 未使用nap()原因:字段类型设计受到了限制。存储信息较少。
array()数组里有一个一个的结构体struct(),每一个结构体struct()对应一个平台属性,也就是数组里一个元素对应一个属性,一个struct()能够存储更多信息。
|