大数据测试 hive 脚本测试时候注意 double 和 decimal 的精度差异示例

baoqiang for 杭州数云测试团队 · 2022年04月27日 · 最后由 攀爬从心开始 回复于 2022年06月07日 · 3379 次阅读

我们先看一下这几个 sql 在 hive 中的返回值:

背景:

在实际 hive 脚本的测试中,常规的一些 sql 和 mysal 类似,那么在测试过程中我们要对使用的每个方法的函数或者引入外部 jar 的一些函数有所了解,解读 sql 含义的时候也需要更加仔细耐心。对于一些比较复杂的 sql 来讲,我们只能进行 sql 的拆解然后对每种类型的数据进行场景覆盖,并且对于输入和输出的结果进行比较,但是对于一些隐藏性的问题,我们还是很难覆盖到的,因此举列子说明一下在对于一些金额或者对于精度要求高的情况下,double 和 decimal 精度差异作为讨论。

  • hive 中整数默认给 int 类型
  • 带有小数位的给 double 类型
  • 可以通过 cast(num as decimal(n,m)) 指定数字类型
  • int 类型是最弱的类型,它和其他两个操作后会被转换
  • double 是最强的类型,和其他两个类型操作时会全部转换成 dluble 类型
  • 使用 double 运算时可能会导致精度丢失,如对精度要求较高,建议全都换成 decimal 类型之后再做操作
select  cast('0.00407' as decimal(18,6) )*2500   --10.175
select  cast('0.00407' as decimal(18,6) )*cast(2500 as  decimal(18,2))  --10.175
select  cast('0.00407' as decimal(18,6) )*cast(2500 as  double)  --10.1749999999999
explain select 200 --返回值类型:int
explain select 200.00 --返回值类型:double
explain select 200*200.00 --返回值类型: double
explain select 200*cast(200.00 as decimal(18,2)) --返回值类型: decimal
explain select 200.00*cast(200.00 as decimal(18,2)) --返回值类型: double
  • 两个 declimal 计算不会造成精度丢失
  • double 和 decimal 计算可能造成精度缺失

decimal 运算先后导致的精度丢失

  • hive 中即使数值都是 decimal,也有可能造成精度缺失 。
  • 因为下一步的计算是以上一个计算结果为基础的,所以任何一部出现无法准确表达的数值时都可能造成精度缺失
select 100/12*6 --50.0
select cast(100 as decimal(18,2))/12*6 --49.999998
select cast(100 as decimal(18,2))/cast(12,decimal(18,2))*cast(6,decimal(18,2)) --49.99998
select cast(100 as decimal(18,2))*6/12 --50

总结

亲爱的小伙伴们,在涉及到金额或者精度要求较为高的场景的时候,特别注意乘法和除法,数据的类型和类型之间的转换问题,此例子就是在下遗漏的一个 BUG,对于这种隐深的问题开发和测试都很难发现,但是这次也是一次累积和更深刻理解一些 hive-sql 的知识。🚀 🚀 🚀 🚀 🚀 🚀 🚀

共收到 2 条回复 时间 点赞

社团已改为公开社团,外部可见。😂

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册