Spark SQL读取Oracle的number类型的数据时精度丢失问题
在程序开发中,使用到了sparkSQL读取Oracle数据库,发现当sparkSQL读取Oracle的number类型字段时,数据的小数经度会出现了丢失的情况。
更为奇怪的是,现有三张Oracle表的字段类型都为number类型,第二种表的数据小数部分出现了丢失,另外两张表则没有问题。三张表的只是在小数位数上存在区别:
第一张表:字段类型是number(7,4)
第二张表:字段类型为number(5,1)
第三张表:字段类型为number(16,4)
参考此文章,是spark的版本bug,并且在Spark2.1.2以上的版本解决了这个问题。(本人此前使用的版本为spark-2.1.1)
在2.1.2版本之前number类型的数据通过spark sql的jdbc读取的时候回变成了IntType类型,这样小数部分就丢失了。 而在Spark2.1.2以上的版本,通过spark sql的jdbc读取的时候回变成了DecimalType类型,小数部分得以保留。
本人在spark2.1.2版本更新发行说明中找到了相关的期号:spark-20555
后续升级了spark版本,问题确实得到了解决。
但却仍然存在一个问题,那就是为什么只是第二张表出现了问题,而其他两张表则没有问题???
我们知道,decimal是标准的sql类型,而number是Oracle特殊的类型,Oracle只是在语法上支持decimal类型,但是在底层实际上它就是number类型,支持decimal类型是为了能把数据从Oracle数据库移到其他数据库中(如DB2等)。因此我们可以看做Oracle中decimal和number是等价的。
上图的description中的第二条信息谈到,decimal(3,2)会变成int类型,确实也印证了这就是spark的版本bug。那结合以上提到的三张表,是不是decimal或者number的小数位小于2位,数据的小数部分就会丢失,而如果大于2位,小数部分就不会丢失呢???目前本人还没有找到相关的依据,姑且算是一种猜想吧。