在使用hive的时候,分隔符是必不可少的,当学习的时候使用的都是常规分隔符,比如:逗号“,”、竖线“|”等,这些键盘上都可以直接输入的字符,但是这些字符只要是键盘上的,在针对复杂的业务逻辑的时候,都会失效。
比如你有一个备注字段,这个字段允许用户输入输入键盘上的任何字符,一旦用户输入了你选择的分隔符,那么Hive在使用这个数据的时候,就会导致hive表中的字段错位。
使用多个组合字符,也可以成为一种选择,但是有些导入导出工具,不支持多字符分隔符,比如:阿里的DATAX就不支持多字符分隔符。
那么现在我们就需要一种字符,是用户输入不了的,计算机又存在的字符,下面这些字符则可以满足需求!
1、特殊字符
以下这些字符是可以在Hive中应用,并且DATAX也支持的:
2、通过digraph输入注意:特殊符号中的^ 和键盘上的^ 字符是不一样的。另外特殊符号中的^和后面跟的字符是一体的,也就是说,两个字符是一个符号。
Vim中显然没有什么特殊字符选择工具,但提供了两种输入特殊字符的方式:
- 1、通过两个字符来输入一个特殊字符(digraph)。
- 2、直接通过编码值(ASCII或Unicode)输入。
其中digraph是一种类似双拼的方法,连续输入两个字符来表示一个特殊字符。需要先按下前导键<Ctrl-K>,例如在编辑模式下输入:
<Ctrl-K>Rg
如上的输入,将会出现®字符,其中"Rg"是该字符的digraph(双拼)。
特殊字符表中的digraph列就是这些字符的双拼输入字符,输入时注意大小写,双拼输入是区分大小写的。
在Windows中是无法输入特殊字符的,可以使用Unicode码进行输入。
例如:要使用^A作为分割字符可以这样写:
create external table city(city_id string,city_name string ) row format delimited fields terminated by '\u0001' location 'hdfs://hadoop01:8090/test/city';
3、测试数据
建表语句:
create external table city(city_id string,city_name string,pinyin string,pingying2 string,code string,db_name string,city_status string,default_areas string,yum_city_name string) row format delimited fields terminated by '\u0000' location 'hdfs://hadoop01:8090/test/city';
如上的代码本人使用的^@字符作为分隔符的。
以下是Eclipse连接Hadoop查看的数据格式样例:
将此文件直接传到Linux服务器中,使用vim打开,可以发现,字段之间的分隔符如下:
Hive查询出来的数据样例:
这里需要说一下,在特殊字符表中有两个^@ 符号,经过本人测试,这两个符号在作为分隔符的时候是一样的,可以认为是一样的。只是输入的时候不一样。
4、查看隐藏字符的方法
在Linux系统中,文本文件中是存在隐藏字符的,需要使用以下命令才能查看到:
cat
命令如下:
cat -A fileName
vim
使用vim进入编辑文件的命令模式,使用以下命令:
set list #显示隐藏字符
set nolist #取消显示隐藏字符
-------------------------第二篇---------------------------
hive中在创建表时,一般会根据导入的数据格式来指定字段分隔符和列分隔符。一般导入的文本数据字段分隔符多为逗号分隔符或者制表符(但是实际开发中一般不用着这种容易在文本内容中出现的的符号作为分隔符),当然也有一些别的分隔符,也可以自定义分隔符。有时候也会使用hive默认的分隔符来存储数据。
hive (fdm_sor)> create table fdm_sor.mytest_tmp2(
> id int comment'编号',
> name string comment '名字'
> );
hive (fdm_sor)> show create table mytest_tmp2;
CREATE TABLE `mytest_tmp2`(
`id` int COMMENT '编号',
`name` string COMMENT '名字')
ROW FORMAT SERDE
'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' --hive默认的分割方式,即行为\n,列为^A
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat' --hive默认的存储格式为textfile
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION --内部表的默认的存储路径
'hdfs://hadoop102:9000/user/hive/warehouse/fdm_sor.db/mytest_tmp2'
TBLPROPERTIES (
'transient_lastDdlTime'='1526176805')
hive (fdm_sor)> create table fdm_sor.mytest_tmp3(
> id int comment'编号',
> name string comment '名字'
> )
> row format delimited fields terminated by '\001' --这里可以指定别的分隔符,如‘\t’,'$'等分隔符
> lines terminated by '\n'
> stored as textfile;
hive (fdm_sor)> show create table fdm_sor.mytest_tmp3;
OK
createtab_stmt
CREATE TABLE `fdm_sor.mytest_tmp3`(
`id` int COMMENT '编号',
`name` string COMMENT '编号')
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\u0001'
LINES TERMINATED BY '\n'
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
'hdfs://hadoop102:9000/user/hive/warehouse/fdm_sor.db/mytest_tmp3'
TBLPROPERTIES (
'transient_lastDdlTime'='1526176859')
如上可以看出hive默认的列分割类型为org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe,而这其实就是^A分隔符,hive中默认使用^A(ctrl+A)作为列分割符,如果用户需要指定的话,等同于row format delimited fields terminated by '\001',因为^A八进制编码体现为'\001'.所以如果使用默认的分隔符,可以什么都不加,也可以按照上面的指定加‘\001’为列分隔符,效果一样。
hive默认使用的行分隔符是'\n'分隔符 ,也可以加一句:LINES TERMINATED BY '\n' ,加不加效果一样。但是区别是hive可以通过row format delimited fields terminated by '\t'这个语句来指定不同的分隔符,但是hive不能够通过LINES TERMINATED BY '$$'来指定行分隔符,目前为止,hive的默认行分隔符仅支持‘\n’字符。否则报错。
hive (fdm_sor)> create table fdm_sor.mytest_tm4(
> id int comment'编号',
> name string comment '名字'
> )
> lines terminated by '\t';
FAILED: ParseException line 5:1 missing EOF at 'lines' near ')'
一般来说hive的默认行分隔符都是换行符,如果非要自定义行分隔符的话,可以通过自定义Inputformat和outputformat类来指定特定行分隔符和列分隔符,一般公司实际开发中也都是这么干的,具体使用,见后面博客。
当然如hive中集合数据类型struct ,map,array,也都有默认的字段分隔符,也都可以指定字段分隔符。hive中对于上述三个集合数据类型的默认字段分隔符是^B,八进制体现为‘\002’,用collection items terminated by '\002'语句来指定分隔符,对于map来说,还有键值之间的分割符,可以用map keys terminated by '\003'(^C)来指定分隔符。