使用hive时,我们偶尔会遇到这样的问题,当你将结果输出到屏幕时,查出的数据往往显示为null,但是当你将结果输出到文本时,却显示为空(即未填充),这是为什么呢?

在hive中有一种假NULL,它看起来和NULL一样,但是实际却不是NULL。

比如下面这样:

[hdfs@dsdc04 ~]$ cat /data6/chenye/baidu_djzs_sessionid/test
\N
NULL

Kris
null

本地的test文件内有五行数据,分别为\N、NULL、   、Kris、null

我们建表将它传到hdfs上,之后再在hive中进行查询,结果如下:

hive> select * from basedatadb.testnull;
OK
NULL
NULL

Kris
null
Time taken: 0.748 seconds, Fetched: 5 row(s)

看清楚了没?发生了什么?在hive中查询时,也显示为五行数据,但是它们分别为NULL、NULL、  、Kris、null。为什么原始数据中的\N在hive中变成了NULL?

再看看,我们本次将结果输出到文本时的情况:

hive> insert overwrite local directory '/data/testnull'
> row format delimited fields terminated by ','
> select *
> from basedatadb.testnull;
Query ID = hdfs_20151020105050_650b3be9-e1af-4236-af4d-71283fb2642b
Total jobs = 1
Launching Job 1 out of 1

Status: Running (Executing on YARN cluster with App id application_1441787030155_0736)

--------------------------------------------------------------------------------
VERTICES STATUS TOTAL COMPLETED RUNNING PENDING FAILED KILLED
--------------------------------------------------------------------------------
Map 1 .......... SUCCEEDED 1 1 0 0 0 0
--------------------------------------------------------------------------------
VERTICES: 01/01 [==========================>>] 100% ELAPSED TIME: 6.39 s
--------------------------------------------------------------------------------
Copying data to local directory /data/testnull
Copying data to local directory /data/testnull
OK
Time taken: 10.633 seconds

------------

打开这个结果显示:

[hdfs@dsdc04 ~]$ cat /data/testnull/*
\N
NULL

Kris
null

也显示为五行,分别为\N、NULL、   、Kris、null。

这种假NULL产生的原因是因为在hive中,空值NULL在底层默认是用'\N'来存储的。

这样的设计存在一个问题是如果实际想存储'\N',那么实际查询出来的也是NULL而不是'\N' 。
Hive给出一种并非完美的解决方法就是可以自定义底层用什么字符来表示NULL。
例如我想用字符'Kris'来表示NULL:

hive> alter table basedatadb.testnull set SERDEPROPERTIES('serialization.null.format' = 'Kris');
OK
Time taken: 0.303 seconds
hive> select * from basedatadb.testnull;
OK
\N
NULL

NULL
null
Time taken: 0.131 seconds, Fetched: 5 row(s)
hive>

看到没有,我们将本张表的空值标识设定为“Kris”后,原本的\N正常显示为\N,原本的Kris显示为NULL。
今后插入到这张表中的'Kris'查询出来就变成了NULL而不是'Kris' 。因为我这个版本的hive还不支持插入操作,所以此处不实验。

然后我又很好奇我们把结果输出到文本会是什么情况,于是我又开启了相关实验,发现:

hive> insert overwrite local directory '/data/testnull2'
> row format delimited fields terminated by ','
> select *
> from basedatadb.testnull;
Query ID = hdfs_20151020113333_9bcd875a-64d7-4494-98d5-aca2af76be3a
Total jobs = 1
Launching Job 1 out of 1

Status: Running (Executing on YARN cluster with App id application_1441787030155_0739)

--------------------------------------------------------------------------------
VERTICES STATUS TOTAL COMPLETED RUNNING PENDING FAILED KILLED
--------------------------------------------------------------------------------
Map 1 .......... SUCCEEDED 1 1 0 0 0 0
--------------------------------------------------------------------------------
VERTICES: 01/01 [==========================>>] 100% ELAPSED TIME: 6.15 s
--------------------------------------------------------------------------------
Copying data to local directory /data/testnull2
Copying data to local directory /data/testnull2
OK
Time taken: 10.921 seconds
hive> Shutting down tez session.
[hdfs@dsdc04 ~]$ cat ^C
[hdfs@dsdc04 ~]$ cat /data/testnull2/*
\N
NULL

\N
null

当我把表的SET SERDEPROPERTIES属性更改为'Kris'后,当我将查询结果输出到文本时,Kris也显示为\N。

结论:
其实上面说的这个假NULL出现的原因就是在默认情况下,即用'\N'表示NULL。可以用SET SERDEPROPERTIES语句修改表的属性,可将其他字段设置为默认的空值的表示。但是值得注意的是:底层存储的文件并没有被修改,经过hive查询和计算的文件却修改了。而'\N'显示为NULL在Hive中又是一个特例,于是就出现了这个假NULL,在开发及分析过程中一定要注意!

以上资源来源于:http://blog.sina.com.cn/s/blog_6ff05a2c010131sh.html

hive中的一种假NULL现象的更多相关文章

  1. Hive中的一种假NULL

    Hive中有种假NULL,它看起来和NULL一摸一样,但是实际却不是NULL. 例如如下这个查询: hive> desc ljn004; OK a       string Time taken ...

  2. 061 hive中的三种join与数据倾斜

    一:hive中的三种join 1.map join 应用场景:小表join大表 一:设置mapjoin的方式: )如果有一张表是小表,小表将自动执行map join. 默认是true. <pro ...

  3. Hive 中的四种排序详解,再也不会混淆用法了

    Hive 中的四种排序 排序操作是一个比较常见的操作,尤其是在数据分析的时候,我们往往需要对数据进行排序,hive 中和排序相关的有四个关键字,今天我们就看一下,它们都是什么作用. 数据准备 下面我们 ...

  4. Hive中的三种不同的数据导出方式介绍

    问题导读:1.导出本地文件系统和hdfs文件系统区别是什么?2.带有local命令是指导出本地还是hdfs文件系统?3.hive中,使用的insert与传统数据库insert的区别是什么?4.导出数据 ...

  5. 044 HIVE中的几种排序

    1.order by:全局排序 select * from emp order by sal; 对于一个reduce才有用. 2.sort by:对于每个reduce进行排序 set mapreduc ...

  6. Hive中的4种Join方式

    common join 普通join,性能较差,存在Shuffle map join 适用情况:大表join小表时,做不等值join 原理:将小表数据广播到各个节点,存储在内存中,在map阶段直接jo ...

  7. HIVE中的几种排序

    1.order by:全局排序 select * from emp order by sal; 2.sort by:对于每个reduce进行排序 set mapreduce.job.reduces=3 ...

  8. Hive总结(八)Hive数据导出三种方式

    今天我们再谈谈Hive中的三种不同的数据导出方式. 依据导出的地方不一样,将这些方式分为三种: (1).导出到本地文件系统. (2).导出到HDFS中: (3).导出到Hive的还有一个表中. 为了避 ...

  9. hive 数据导出三种方式

    今天我们再谈谈Hive中的三种不同的数据导出方式.根据导出的地方不一样,将这些方式分为三种:(1).导出到本地文件系统:(2).导出到HDFS中:(3).导出到Hive的另一个表中.为了避免单纯的文字 ...

随机推荐

  1. append,appendTo和prepend #1daae2

    1.append(content)                                                                                   ...

  2. MongoDB环境准备

    1.安装MongoDB MongoDB的安装非常简单,只需要将下载的MongoDB的压缩文件解压到任意目录,并将其中的bin目录加入到系统的path环境变量中即可 2.启动MongoDB 在启动Mon ...

  3. DataSet的灵活,实体类的方便,DTO的效率:SOD框架的数据容器,打造最适合DDD的ORM框架

    引言:DDD的困惑 最近,我看到园子里面有位朋友的一篇博客 <领域驱动设计系列(一):为何要领域驱动设计? >文章中有下面一段话,对DDD使用产生的疑问: •没有正确的使用ORM, 导致数 ...

  4. java集合-集合大家族

    在编写 Java 程序中,我们最常用的除了八种基本数据类型,String 对象外还有一个集合类,在我们的的程序中到处充斥着集合类的身影!Java 中集合大家族的成员实在是太丰富了,有常用的 Array ...

  5. babel 无法解析jsx (webpack react )

    webpack.config.js的配置如下图: 报错: 修改webpack.config.js文件,如下即可:

  6. 前端安全之XSS攻击

    XSS(cross-site scripting跨域脚本攻击)攻击是最常见的Web攻击,其重点是“跨域”和“客户端执行”.有人将XSS攻击分为三种,分别是: 1. Reflected XSS(基于反射 ...

  7. Ajax基本概念和原理

    什么是Ajax Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. Ajax的全称是Asynchronous JavaScript and XML,即异步JavaScript+X ...

  8. 深入理解javascript---命名函数表达式

    简单的说,命名函数表达式只有一个用户,那就是在Debug或者Profiler分析的时候来描述函数的名称,也可以使用函数名实现递归,但很快你就会发现其实是不切实际的.当然,如果你不关注调试,那就没什么可 ...

  9. 错误 24 无法嵌入互操作类型“ESRI.ArcGIS.Geometry.PointClass”。请改用适用的接口。 E:\MyGIS\MyGIS\Form1.cs 78 37 MyGIS

    解决办法:选中那个引用,在属性页,将“嵌入互操作”设置为false

  10. 怎么让一个项目里swift与OC可以兼容混合开发?

    在苹果推出了swift语言之后,很多人担心OC很快会被取代,但是苹果方面表示2年内不会摒弃OC.但现在也快了啊.有的开发团队已经开始基于swift开发,但是有很多旧的框架还没来得及用swift写出来, ...