在使用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)來指定分隔符。
參考:https://blog.csdn.net/qq_26442553/article/details/80297028
https://my.oschina.net/u/3754001/blog/2870327