Hive默認分隔符和默認NULL值


HIve系統默認分隔符。通常下面2中情況我們需要需要用到分隔符

1,制作table的輸入文件,有時候我們需要輸入一些特殊的分隔符

2,把hive表格導出到本地時,系統默認的分隔符是^A,這個是特殊字符,直接cat或者vim是看不到的

分隔符在HIVE中的用途

分隔符

描述

\n

對於文本文件來說,每行都是一條記錄,因此換行符可以分隔記錄

^A(Ctrl+A)

用於分隔字段(列)。在CREATE TABLE語句中可以使用八進制編碼\001表示

^B(Ctrl+B)

用於分隔ARRAY或者STRUCT中的元素,或用於MAP中鍵-值對之間的分隔。在CREATE TABLE語句中可以使用八進制編碼\002表示

^C(Ctrl+C)

用於MAP中鍵和值之間的分隔。在CREATE TABLE語句中可以使用八進制編碼\003表示

Hive 中沒有定義專門的數據格式,數據格式可以由用戶指定,用戶定義數據格式需要指定三個屬性:列分隔符(通常為空格、”\t”、”\x001″)、行分隔符(”\n”)以及讀取文件數據的方法。
由於在加載數據的過程中,不需要從用戶數據格式到 Hive 定義的數據格式的轉換,因此,Hive 在加載的過程中不會對數據本身進行任何修改,而只是將數據內容復制或者移動到相應的 HDFS 目錄中。

sql:

row format delimited 
fields terminated by '\001' 
collection items terminated by '\002' 
map keys terminated by '\003'
lines terminated by '\n' 
stored as textfile; 

HIVE表中默認將NULL存為\N,可查看表的源文件(hadoop fs -cat或者hadoop fs -text),文件中存儲大量\N。

這樣造成浪費大量空間。而且用java、python直接進入路徑操作源數據時,解析也要注意。
另外,hive表的源文件中,默認列分隔符為\001(SOH),行分隔符為\n(目前只支持\n,別的不能用,所以定義時不需要顯示聲明)。元素間分隔符\002,map中key和value的分隔符為\003。

舉例,如源文件中一條記錄為:

 

可以看出存儲NULL的\N 浪費了大量空間。

但hive的NULL有時候是必須的:
1)hive中insert語句必須列數匹配,不支持不寫入,沒有值的列必須使用null占位。

2)hive表的數據文件中按分隔符區分各個列。空列會保存NULL(\N)來保留列位置。但外部表加載某些數據時如果列不夠,如表13列,文件數據只有2列,則在表查詢時表中的末尾剩余列無數據對應,自動顯示為NULL。

可以看出存儲NULL的\N 浪費了大量空間。

但hive的NULL有時候是必須的:
  1)hive中insert語句必須列數匹配,不支持不寫入,沒有值的列必須使用null占位。

  2)hive表的數據文件中按分隔符區分各個列。空列會保存NULL(\N)來保留列位置。但外部表加載某些數據時如果列不夠,如表13列,文件數據只有2列,則在表查詢時表中的末尾剩余列無數據對應,自動顯示為NULL。

所以,NULL轉化為空字符串,可以節省磁盤空間,實現方法有幾種

1)建表時直接指定(兩種方式)

a、用語句
實現,注意兩者必須一起使用,如

ROW FORMAT SERDE ‘org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe’
    with serdeproperties('serialization.null.format' = '')
--結合使用:
CREATE TABLE hive_tb (id int,name STRING) PARTITIONED BY ( `day` string,`type` tinyint COMMENT '0 as bid, 1 as win, 2 as ck', `hour` tinyint) ROW FORMAT SERDE ‘org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe’ WITH SERDEPROPERTIES ( ‘field.delim’='/t’, ‘escape.delim’='//’, ‘serialization.null.format'='' ) STORED AS TEXTFILE;

b、或者通過ROW FORMAT DELIMITED NULL DEFINED AS '' 如

   CREATE TABLE hive_tb (id int,name STRING)
   PARTITIONED BY ( `day` string,`type` tinyint COMMENT '0 as bid, 1 as win, 2 as ck', `hour` tinyint)
   ROW FORMAT DELIMITED 
        NULL DEFINED AS '' 
   STORED AS TEXTFILE;

 

2)修改已存在的表

    alter table hive_tb set serdeproperties('serialization.null.format' = '');

節省空間的驗證結果如下:

hadoop fs -du /hivedata/warehouse/pmp.db/hive_tb/day=2016-05-14/type=1/hour=00/0*
1137
hadoop fs -du /hivedata/warehouse/pmp.db/hive_tb/day=2016-05-14/type=1/hour=01/0*
319753
-----------------------------------
hadoop fs -du /hivedata/warehouse/pmp.db/hive_tb/day=2016-05-14/type=1/hour=00/0*
885
hadoop fs -du /hivedata/warehouse/pmp.db/hive_tb/day=2016-05-14/type=1/hour=01/0*
249529

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM