Hive中的一种假NULL
Hive中有種假NULL,它看起來和NULL一摸一樣,但是實際卻不是NULL。
例如如下這個查詢:
hive> desc ljn004;
OK
a??????string
Timetaken: 0.237 seconds
?
hive> select a fromljn004;
OK
NULL
Timetaken: 46.232 seconds
?
看上去好像ljn004的a字段保存了一個?NULL,
但是換一個查詢會發現它和NULL并不一樣:
hive> select a from ljn004 where a isnull;
OK
Timetaken: 62.56 seconds
來看一下實際存儲的是什么:
hive> select * fromljn004;
OK
\N
Timetaken: 1.232 seconds
hive> select a from ljn004 where a ='\\N';
OK
NULL
Timetaken: 72.933 seconds
ljn004的a字段實際存儲的是一個'\N',a ='\\N'是因為Hive中'\'是轉義字符,需要對'\'進行一次轉義,所以變成'\\N'。
這種假NULL產生的原因實際上源于對表的錯誤操作。在Hive中,空值NULL在底層默認是用'\N'來存儲的,看一個例子:
hive> create table ljn005 (col1string);
OK
Timetaken: 1.258 seconds
1 Rowsloaded to ljn005
OK
Timetaken: 63.727 seconds
hive> insert overwrite table ljn005 selectNULL from dual;
然后看一下底層的數據存儲:
$hadoop fs -cat/group/hive/ljn005/attempt_201205041518_256192_m_000000_0
\N
可以看到底層數據將NULL存儲成了'\N'?。
這樣的設計存在一個問題是如果實際想存儲'\N',那么實際查詢出來的也是NULL而不是'\N'?。
Hive給出一種并非完美的解決方法就是可以自定義底層用什么字符來表示NULL。
例如我想用字符'a'來表示NULL:
hive> alter table ljn005 SETSERDEPROPERTIES('serialization.null.format' ='a');
OK
Timetaken: 0.175 seconds
?
hive> insert overwrite table ljn005 selectNULL from dual;
1 Rowsloaded to ljn005
OK
Timetaken: 62.66 seconds
?
再看一下底層的存儲:
$hadoop fs -cat/group/hive/ljn005/attempt_201205041518_256764_m_000000_0
a
?
這時候底層的存儲就變成了'a'?,今后插入到這張表中的'a'查詢出來就變成了NULL而不是'a'?。
?
其實上面說的這個假NULL出現的原因就是在默認情況下(即用'\N'表示NULL),插入了NULL值,然后又用SETSERDEPROPERTIES語句修改了存儲NULL的字符串。這時候表的屬性修改了,但是底層存儲的文件并沒有修改。而'\N'顯示為NULL在Hive中又是一個特例,于是就出現了這個假NULL,在開發過程中一定要注意!
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Hive中的一种假NULL的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql日期处理的一些实现
- 下一篇: 自然语言处理应用和过程的一些理解