序列化和反序列化
文件读取/解析的方式
create table t1(
id int,
name string
)
row format delimited
fields terminated by ','
;
0,7369,SMITH,CLERK,7902,1980-12-17,800,null,20
从文件里进行查询时,会不会在内存里产生hive的相关对象啊
select * from student;
一行记录一行记录的显示。
select过程 磁盘上的数据--->row对象 <------反序列化 InputFormat
insert过程 row对象---->磁盘上的数据 <-----序列化 OutputFormat
复制代码
在建表语句中,指定了记录的切分格式以及字段的切分符号。实际上,hive在解析文件的时候,涉及到了两个类型。
- 一个类用于从文件中读取一条一条的记录(根据记录分隔符确定一条记录)
row format: 用于指定使用什么格式解析一行的数据
delimited : 表示使用 org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe 进行行的内容解析 - 一个类用于从上面读到的记录中切分出一个一个的字段(根据指定字符作为分隔符)
fields terminated by: 表示用什么字符进行字段之间的分隔
lines terminated by: 表示用什么字符进行行之间的分隔
强调:hive在select时,这个过程是将字节序列转成hive中的java对象。
hive在insert时,这个过程是将hive中的java对象转成字节序列。
Serde简介
概念
- SerDe是“Serializer and Deserializer”的简称。
- Hive使用SerDe(和FileFormat)来读/写表的Row对象。
- HDFS文件-> InputFileFormat -> <key,value> -> Deserializer -> Row对象
- Row对象->Serializer -> <key,value> -> OutputFileFormat -> HDFS文件
注意,“key”部分在读取时会被忽略,而在写入时始终是常数。基本上Row对象存储在“值”中。
注意,org.apache.hadoop.hive.serde是一个过时的SerDe库。使用最新版本的org.apache.hadoop.hive.serde2。
文末扫码领取大数据学习礼包!
常用的Serde
- csv: 逗号分隔值
- tsv: tab分隔值
- json: json格式的数据
- regexp: 数据需要复合正则表达式
LazySimpleSerDe
Hive分隔符
- 行分隔符:\n
- 列分隔符:^A
在Hive中,建表时一般用来来指定字段分隔符和列分隔符。一般导入的文本数据字段分隔符多为逗号分隔符或者制表符(但是实际开发中一般不用着这种容易在文本内容中出现的的符号作为分隔符),当然也有一些别的分隔符,也可以自定义分隔符。有时候也会使用hive默认的分隔符来存储数据。在建表时通过下面语法来指定:
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' -- 指定列分隔符
LINES TERMINATED BY '\n' -- 指定行分隔符
默认情况下行分隔符是\n, 列分隔符一般是不容易在文本中出现的字符,开发中大部分用TAB,但有时候TAB也有可能重复,这时候可以使用Hive的默认分隔符的.
hive中默认使用^A(ctrl+A)作为列分割符,如果用户需要指定的话,等同于row format delimited fields terminated by '\001',因为^A八进制编码体现为'\001'.所以如果使用默认的分隔符,可以什么都不加,也可以按照上面的指定加‘\001’为列分隔符,效果一样。
hive默认使用的行分隔符是'\n'分隔符 ,默认是通过row format delimited fields terminated by '\t'这个语句来指定不同的分隔符,但是hive不能够通过LINES TERMINATED BY ''来指定行分隔符,目前为止,hive的默认行分隔符仅支持‘\n’字符。
数据样本
1001^Azs^A23
1002^Alis^A24
复制代码
建表
create table if not exists csv1(
uid int,
uname string,
age int
); -- 格式都没有指定,默认使用的就是LazySimpleSerde,记录分隔符是\n,列分隔符是^A
复制代码
导入数据
load data local inpath './data/csv1.txt' overwrite into table csv1;
复制代码
CSV
分隔符:
列分隔符:逗号
CSV格式的文件也称为逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可
以不是逗号。),其文件以纯文本形式存储表格数据(数字和文本)。CSV文件由任意数目的记录组成,记录间以换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。
在CSV的Serde中有以下三个默认属性
- 默认转义字符(DEFAULT_ESCAPE_CHARACTER): \ <--反斜线
- 默认引用字符(DEFAULT_QUOTE_CHARACTER): " <--双引号
- 默认分隔符(DEFAULT_SEPARATOR): , <-逗号
数据样本
1001,zs,23
1002,lis,24
复制代码
建表
drop table csv2;
create table if not exists csv2(
uid int,
uname string,
age int
)
row format serde 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
;
复制代码
导入数据:
load data local inpath './data/csv2.txt' into table csv2;
复制代码
自定义字段分隔符、字段引用字符、转义字符
如果不想使用默认分隔符的话,可以使用自定义分隔符,原理其实就是向底层的API的方法的参数中传入指定分隔值
可以指定字段分隔符、字段引用字符、转义字符
create table csv3(
uid int,
uname string,
age int
)
row format serde 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
with serdeproperties(
"separatorChar"="7"
)
stored as textfile
;
load data local inpath './data/csv3.txt' into table csv3;
复制代码
json serde :
说明
- json serde 可以是自己写的jar包也可以是第三方的jar包
- 要把这种jar包添加到hive的class path中
- add jar ./data/json-serde-1.3.8-jar-with-dependencies.jar;
准备数据
{"uid":"1","uname":"gaoyuanyuan","age":"18"}
{"uid":"2","uname":"gaojianzheng","age":"42"}
复制代码
建表语句
drop table json1;
create table if not exists json1(
uid int,
uname string,
age int
)
row format serde 'org.openx.data.jsonserde.JsonSerDe'
stored as textfile
;
复制代码
导入数据
load data local inpath './data/json1.txt' into table json1;
复制代码
Regex Serde
数据准备
01||zhangsan||23
02||lisi||24
复制代码
说明
hive默认情况下只支持单字节分隔符,如果数据中的分隔符是多字节的,则hive默认是处理不了的。需要使用正则Serde
建表
create table if not exists t_regex(
id string,
uname string,
age int
)
row format serde 'org.apache.hadoop.hive.serde2.RegexSerDe'
with serdeproperties(
'input.regex'='(.*)\\|\\|(.*)\\|\\|(.*)',
'output.format.string'='%1$s %2$s %3$s'
)
stored as textfile
;
复制代码
导入数据
load data local inpath './data/regex.txt' into table t_regex;