HIVE踩坑——NULL和空字符串處理


這里我們針對在HIVE中遇到的NULL和空字符串問題進行簡單探討,避免踩坑!!!

簡單探索

首先新建一張測試表test_01,用作后續測試

CREATE  TABLE IF NOT EXISTS `test_01`(
  `id` INT, `name` STRING,`age` INT, `score` FLOAT)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE;

新增簡單的幾條測試數據,具體如下

 insert overwrite  table test_01
  select NULL,NULL,10,95
  union all select 2 ,'',10,95
  union all select 3 ,'Lucy',15,NULL
  union all select 4,'Jack',15,100;

查看新增數據

hive (tmp)> select * from test_01;
OK
NULL    NULL    10    95.0
2                10    95.0
3        Lucy    15    NULL
4        Jack    15    100.0

底層HDFS文件默認存儲格式

[root@nd2 wh]# hadoop fs -cat /user/hive/warehouse/tmp.db/test_01/000000_0
\N,\N,10,95.0
2,,10,95.0
3,Lucy,15,\N
4,Jack,15,100.0

得出結論:
默認情況下,STRING類型的數據如果為" “,底層HDFS文件默認存儲則是” ";
INT與STRING等類型的數據如果為NULL,底層HDFS默認默認存儲為 \N;

這里我們根據name條件查詢

--條件為 name is null
hive (tmp)> select * from test_01 where name is null;
NULL    NULL    10    95.0
--條件為name = ''
hive (tmp)> select * from test_01 where name = '';
2        10    95.0
--條件為id is null
hive (tmp)> select * from test_01 where id is null;
NULL    NULL    10    95.0

可以得出結論:
默認情況下,對於INT可以使用is null來判斷空;
而對於STRING類型,條件is null 查出來的是\N的數據;而條件 =" “,查詢出來的是” "的數據。

實際情況

在HIVE使用中,很多時候我們可能需要使用底層HDFS文件用作數據存儲或其它數據遷移,備份。這個時候底層HDFS文件中\N和" "處理就顯得很重要了(不同的應用可能對底層文件處理不一樣)。
在HIVE中,一般我們會在新建表之后執行

--自定義底層用什么字符來表示NULL。這里用''來表示。換句話說就是讓null和''等價,底層HDFS讓null不顯示。
ALTER TABLE test_01 SET SERDEPROPERTIES ('serialization.null.format'='');

我們重新插入數據,查詢結果

hive (tmp)> select * from test_01;
OK
NULL    NULL    10    95.0
2        NULL    10    95.0
3        Lucy    15    NULL
4        Jack    15    100.0

底層HDFS文件存儲的數據格式為

[root@nd2 wh]# hadoop fs -cat /user/hive/warehouse/tmp.db/test_01/000000_0
,,10,95.0
2,,10,95.0
3,Lucy,15,
4,Jack,15,100.0

我們發現底層數據保存的是" ",通過查詢顯示的結果時NULL。
注意:
我們使用is null或者 = " “都是根據查詢顯示的結果進行過濾。而不是根據底層文件格式。
查詢空值用is null,如果用=” ",查詢不到數據。

--條件為 name is null
hive (tmp)> select * from test_01 where name is null;
NULL    NULL    10    95.0
2    NULL    10    95.0
--條件為 name =''
hive (tmp)> select * from test_01 where name ='';
OK
Time taken: 4.058 seconds

 

原文鏈接:https://blog.csdn.net/henrrywan/java/article/details/90612378


免責聲明!

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



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