hive学习笔记之二:复杂数据类型

欢迎访问我的GitHub
内容:所有原创文章分类和汇总 , 及配套源码 , 涉及Java、Docker、Kubernetes、DevOPS等;
本篇概览

  • 作为《hive学习笔记》的第二篇 , 前面咱们了解了基本类型 , 本篇要学习的是复杂数据类型;
  • 复杂数据类型一共有四种:
  1. ARRAY:数组
  2. MAP:键值对
  3. STRUCT:命名字段集合
  4. UNIONTYPE:从几种数据类型中指明选择一种 , UNION的值必须与这些数据类型之一完全匹配;
  • 接下来逐个学习;
准备环境
  1. 确保hadoop已经启动;
  2. 进入hive控制台的交互模式;
  3. 执行以下命令 , 使查询结果中带有字段名:
set hive.cli.print.header=true;ARRAY
  1. 创建名为t2的表 , 只有person和friends两个字段 , person是字符串类型 , friends是数组类型 , 通过文本文件导入数据时 , person和friends之间的分隔符是竖线 , friends内部的多个元素之间的分隔符是逗号 , 注意声明分隔符的语法:
create table if not exists t2(person string,friends array)row format delimited fields terminated by '|'collection items terminated by ',';
  1. 创建文本文件002.txt , 内容如下 , 可见只有两条记录 , 第一条person字段值为tom , friends字段里面有三个元素 , 用逗号分隔:
tom|tom_friend_0,tom_friend_1,tom_friend_2jerry|jerry_friend_0,jerry_friend_1,jerry_friend_2,jerry_friend_3,jerry_friend_4,jerry_friend_5
  1. 执行以下语句 , 从本地的002.txt文件导入数据到t2表:
load data local inpath '/home/hadoop/temp/202010/25/002.txt' into table t2;
  1. 查看全部数据:
hive> select * from t2;OKt2.person t2.friendstom ["tom_friend_0","tom_friend_1","tom_friend_2"]jerry ["jerry_friend_0","jerry_friend_1","jerry_friend_2","jerry_friend_3","jerry_friend_4","jerry_friend_5"]Time taken: 0.052 seconds, Fetched: 2 row(s)
  1. 查询friends中的某个元素的SQL:
select person, friends[0], friends[3] from t2;执行结果如下 , 第一条记录没有friends[3] , 显示为NULL:
hive> select person, friends[0], friends[3] from t2; OKperson _c1 _c2tom tom_friend_0 NULLjerry jerry_friend_0 jerry_friend_3Time taken: 0.052 seconds, Fetched: 2 row(s)
  1. 数组元素中是否包含某值的SQL:
select person, array_contains(friends, 'tom_friend_0') from t2;执行结果如下 , 第一条记录friends数组中有tom_friend_0 , 显示为true , 第二条记录不包含 , 就显示false:
hive> select person, array_contains(friends, 'tom_friend_0') from t2;OKperson _c1tom truejerry falseTime taken: 0.061 seconds, Fetched: 2 row(s)
  1. 第一条记录的friends数组中有三个元素 , 借助LATERAL VIEW语法可以把这三个元素拆成三行 , SQL如下:
select t.person, single_friendfrom (select person, friendsfromt2 where person='tom') t LATERAL VIEW explode(t.friends) v as single_friend;执行结果如下 , 可见数组中的每个元素都能拆成单独一行:
OKt.person single_friendtom tom_friend_0tom tom_friend_1tom tom_friend_2Time taken: 0.058 seconds, Fetched: 3 row(s)
  • 以上就是数组的基本操作 , 接下来是键值对;
MAP , 建表 , 导入数据
  • 接下来打算创建名为t3的表 , 只有person和address两个字段 , person是字符串类型 , address是MAP类型 , 通过文本文件导入数据时 , 对分隔符的定义如下:
  1. person和address之间的分隔符是竖线;
  2. address内部有多个键值对 , 它们的分隔符是逗号;
  3. 而每个键值对的键和值的分隔符是冒号;
  • 满足上述要求的建表语句如下所示:
create table if not exists t3(person string,address map)row format delimited fields terminated by '|'collection items terminated by ',' map keys terminated by ':';
  • 创建文本文件003.txt , 可见用了三种分隔符来分隔字段、MAP中的多个元素、每个元素键和值:
tom|province:guangdong,city:shenzhenjerry|province:jiangsu,city:nanjing
  • 导入003.txt的数据到t3表:
load data local inpath '/home/hadoop/temp/202010/25/003.txt' into table t3;MAP , 查询
  1. 查看全部数据:
hive> select * from t3;OKt3.person t3.addresstom {"province":"guangdong","city":"shenzhen"}jerry {"province":"jiangsu","city":"nanjing"}Time taken: 0.075 seconds, Fetched: 2 row(s)
  1. 查看MAP中的某个key , 语法是field[“xxx”]:
hive> select person, address["province"] from t3;OKperson _c1tom guangdongjerry jiangsuTime taken: 0.075 seconds, Fetched: 2 row(s)