1、hvie的SerDe机制
其中ROW FORMAT是语法关键字,DELIMITED和SERDE二选其一。本次我们主要学习DELIMITED关键字相关知识点
如果使用delimited: 表示底层默认使用的Serde类:LazySimpleSerDe类来处理数据。
如果使用serde:表示指定其他的Serde类来处理数据,支持用户自定义SerDe类。
Hive默认的序列化类: LazySimpleSerDe
包含4种子语法,分别用于指定字段之间、集合元素之间、map映射 kv之间、换行的分隔符号。
在建表的时候可以根据数据的类型特点灵活搭配使用。
COLLECTION ITEMS TERMINATED BY '分隔符' : 指定集合类型(array)/结构类型(struct)元素的分隔符
MAP KEYS TERMINATED BY '分隔符' : 表示映射类型(map)键值对之间用的分隔
2、复杂类型
复杂类型建表格式:
...
[row format delimited] # hive的serde机制
[fields terminated by '字段分隔符'] # 自定义字段分隔符固定格式
[collection ITEMS terminated by '集合分隔符'] # 自定义array同类型集合和struct不同类型集合
[map KEYS terminated by '键值对分隔符'] # 自定义map映射kv类型
[lines terminated by '\n'] # # 默认即可
...;
hive复杂类型: array struct map
array类型: 又叫做数组类型。用来存储相同类型的数据集合
建表指定类型: array<元素的数据类型>
取值: 字段名[索引/下标/角标]。索引是从0开始
获取长度: size(字段名)
判断是否包含某个数据: array_contains(字段名)
struct类型:又叫做结构类型。可以存储不同了类型的数据集合
建表指定类型: struct<字段名称1:数据类型,字段名称2:数据类型...>
取值: 字段名.key键的名称
map类型: 又叫做映射类型。存储的是key-value键值对数据
建表指定类型: map<key的类型,value的类型>
取值: 字段名[key的名称]
获取长度: size(字段名),实际获取的是key-value键值对的对数
获取所有key: map_keys(字段名)
获取所有value: map_values(字段名)
3、array示例
需求: 已知data_for_array_type.txt文件,存储了学生以及居住过的城市信息,要求建hive表把对应的数据存储起来
use day07;
-- 创建表
create table array_tb(
name string,
work_location array<string>
)
row format delimited fields terminated by '\t'
collection items terminated by ','; -- 指定array数组中元素间的分隔符
-- load加载数据
load data inpath '/dir/data_for_array_type.txt' into table array_tb;
-- 验证数据
select * from array_tb;
-- array专有的操作
-- 函数:具备特殊功能的代码,例如size
-- size(work_location) 统计数组中有多少个元素。该案例中也就是统计你去多少个城市工作过
select name,size(work_location) as city_cnt from array_tb;
-- 数组字段名称[索引/下标/角标]。索引是从0开始
select name,work_location[-1] from array_tb;
select name,work_location[0] from array_tb; -- 取数组中的第一个元素
select name,work_location[1] from array_tb; -- 取数组中的第二个元素
select name,work_location[10] from array_tb; -- 如果根据索引取不到对应的元素,那么返回的是null空值。null值(你没有去参加考试)和0(参加考试,但是考了0分)是不一样
-- 判断数组中是否存在某个元素/数据
-- array_contains:是一个函数,用来判断元素在数组中是否存在。如果存在返回true;如果不存在返回false
select name,array_contains(work_location,"chengdu") from array_tb;
4、struct示例
需求: 已知data_for_struct_type.txt文件存储了用户姓名和年龄基本信息,要求建hive表把对应的数据存储起来
use day07;
-- 创建表
create external table singer_struct(
id int,
info struct<name:string,num:int>
)row format delimited fields terminated by '#'
collection items terminated by ':';-- 指定struct中元素间的分隔符
-- 加载数据
load data inpath '/dir/data_for_struct_type.txt' into table singer_struct;
-- 验证数据
select * from singer_struct;
-- struct中特有的操作
-- 如果想要看struct中的具体信息,需要通过 struct字段名称.key键
select id,info.name,info.num from singer_struct;
select id,info.name,info.num,info.aaaa from singer_struct;
-- struct中不支持size()函数
-- select id,size(info) from singer_struct;
原因: 如果访问struct中不存在的key会报如上的问题。
5、map示例
需求: 已知data_for_map_type.txt文件存储了每个学生详细的家庭信息,要求建hive表把对应数据存储起来
use day07;
-- 创建表
create table star_map(
id int,
name string,
family map<string,string>, -- 前面的string是key的数据类型,后面的string是value的数据类型
age int
)row format delimited fields terminated by ',' -- 指定字段间的分隔符
collection items terminated by '#' -- 指定map中key-value键值对间的分隔符
map keys terminated by ':'; -- 指定key-value键值对里面的分隔符
-- load导入数据到Hive表中
load data inpath '/dir/data_for_map_type.txt' into table star_map;
-- 数据验证
select * from star_map;
-- map数据类型的特殊操作
select id,name,age,family['father'] as father,family['mother'] as mother from star_map;
-- 获取map中所有key的信息
select id,name,age,map_keys(family) as keys from star_map;
-- 获取map中所有key的信息,之后,再通过array获取数据的方式,获取指定索引的元素值
select id,name,age,map_keys(family),map_keys(family)[1] as keys from star_map;
-- 获取map中所有value的信息
select id,name,age,map_values(family) as keys from star_map;
-- 获取map中所有value的信息,之后,再通过array获取数据的方式,获取指定索引的元素值
select id,name,age,map_values(family),map_values(family)[2] as keys from star_map;
-- size函数:在map中,是用来获取key-value键值对的对数
select id,name,age,size(family) from star_map;
-- array_contains函数
select id,name,age,map_keys(family),array_contains(map_keys(family),"brother") from star_map;