大数据分析组件Hive-集合数据结构

Hive的数据结构

  • 前言
  • 一、array数组类型
  • 二、map键值对集合类型
  • 三、struct结构体类型

    前言

    Hive是一个基于Hadoop的数据仓库基础设施,用于处理大规模分布式数据集。它提供了一个类似于SQL的查询语言(称为HiveQL),允许用户以类似于关系型数据库的方式查询和分析存储在Hadoop集群中的数据。

    Hive常作为离线数仓的分析工具,当面临Json数据时,Hive需要用到其数据结构构建出一张Json表才得以操作Json数据;(Hive4.0推出了Json解析)

    一、array数组类型

    数组是一组具有相同类型的变量的集合。 这些变量称为数组的元素,每个数组元素都有一个编号,编号从零开始。

    数组类型的创建:

    drop table if exists test_datatype;
    create external table test_datatype(
        ids array,
    ) comment '数据结构测试表'
    location 'test/test_datatype';
    

    创建表字段时,使用Array类型需要声明其泛型,如果在后续的操作中,向该表字段插入了一个包含string类型的array,Hive 在数据加载过程中会根据目标表的声明进行数据类型推断和转换。如果插入的数组元素与目标表声明的数据类型不匹配,Hive 会尝试进行隐式类型转换。在这种情况下,Hive 会尝试将字符串转换为整数类型。

    Tip:隐式类型转换可能导致数据丢失或错误。如果类型转换失败Hive 可能会将其转换为 NULL 值。

    以下构建一个简单的array数组对象:

    ====查询语句====
    select
           ids,
           `array`(ids[0],ids[6]),
            array_contains(ids,'milet')
    from (
         select `array`("aimyon","aimer","vaundy","Ado",1,3.6) as ids
             )t1
             
    ====执行结果====
    ids>>>["aimyon","aimer","vaundy","Ado","1","3.6"]
    `array`(ids[0],ids[5])>>>["aimyon",null]
    array_contains(ids,'milet')>>> false
    
    1. Array 类型可以存储具有相同数据类型的元素。这意味着数组中的每个元素都应该是相同的数据类型。上述的Hql中使用了string和int类型,但是查询结果显示的都是string类型。
    2. Array类型通过下标取出元素,如果下标越界,取出的元素为null
    3. array_contains()能够检索数组是否包含该元素,该函数返回布尔类型。

    二、map键值对集合类型

    Map 类型是一种键值对的集合,其中的键和值可以是任何 Hive 支持的数据类型。Map 类型用于表示一种关联关系,类似于其他编程语言中的字典或哈希表。

    Map类型的创建:

    drop table if exists test_datatype;
    create external table test_datatype(
        dat map) comment '数据结构测试表'
    location 'test/test_datatype';
    

    创建Map类型时,需要声明其键值对泛型,Map 类型的语法为 MAP,其中 key_type 和 value_type 分别表示键和值的数据类型。

    以下构建一个简单的map对象:

    ====查询语句====
    select
        dat,
        dat['a'],
        map_keys(dat),
        `if`(array_contains(map_keys(dat),"a"),"true","false")
    from (
         select `map`('a','b',1,'d') dat
             )t;
             
    ====执行结果====
    dat>>>{"a":"b","1":"d"}
    dat['a']>>>b
    map_keys(dat)>>>["a","1"]
    `if`(array_contains(map_keys(dat),"a"),"true","false")>>>true
    

    map类型使用map[‘key_name’]的方式取出值,并且hive提供了map_keys,map_values获取所用的key和value,这在一些判断场景下非常好使。

    Tip:map的key的类型可以不统一,但是value类型必须统一。

    三、struct结构体类型

    在 Hive 中,结构体(Struct)类型是一种用于组合多个字段的复合数据类型。结构体类型允许你在一个列中存储多个相关的值,并将它们作为一个单元进行处理。

    结构体类型由多个字段组成,每个字段都有一个名称和一个数据类型。你可以将结构体类型用作表的列类型,或者作为其他复合数据类型(如数组或映射)的元素类型。

    struct类型的创建:

    drop table if exists test_datatype;
    create external table test_datatype(
        obj struct) comment '数据结构测试表'
    location 'test/test_datatype';
    

    创建struct结构体时,需要声明所有使用到的类型,结构体创建之后,其属性不能再做更改。

    以下构建一个简单的struct对象:

    ====查询语句====
    select struct('a','b','c','d') >>>{"col1":"a","col2":"b","col3":"c"}
    select name_struct('a','b','c',1) >>>{"a":"b","c":1}
     
    select obj,
           obj.a
    from (
             select named_struct('a', 'b', 'c', 1) obj
         ) t1;
    ====执行结果====
    obj>>> {"a":"b","c":1}
    obj.a>>> b
    
    1. 结构体通过点的方式访问元素
    2. 结构体与map不同,一旦创建属性个数就不能更改。
    3. 结构体定义后,其类型不能做更改< name:string,age:int >;map类型定义后其每个元素的值类型就需要确定了map< string:stiring >

    总结:

    遇到Json属性为 {key1:value1,key2:value2 …}

    1. value类型都统一的,并且个数不确定的可以使用map类型。
    2. value类型不统一,并且个数确定的可以使用struct类型。

    遇到类似数组的json数据:

     "actions": [{ -- 动作(事件)
        "action_id": "favor_add",   -- 动作id
        "item": "3",                -- 目标id
        "item_type": "sku_id",      -- 目标类型
        "ts": 1585744376605         -- 动作时间戳
      }
    
    1. 数据结构可以嵌套使用:array< struct < key1:string,key2:int > >
    2. 上述json中actions为数组,元素个数不确定并且元素都能够用struct

    array<泛型> map struct

    具体问题具体分析,根据数据情况选择合适的数据结构。