MySQL中包含了decimal类型用于对精度要求较高的场景,比如说账户余额相关的,关于decimal的基础知识推荐阅读官方文档;本文主要讨论一下对decimal进行运算时的默认类型转化。
admin@test03:57:24>create table test(`deci` decimal(25,2) DEFAULT NULL); Query OK, 0 rows affected (0.06 sec) admin@test03:57:37>insert into test values(591646.44); Query OK, 1 row affected (0.00 sec) |
执行如下查询
admin@test03:58:00>select deci-"1.111" from test; +-------------------+ | deci-"1.111" | +-------------------+ | 591645.3289999999 | +-------------------+ 1 row in set (0.13 sec) |
在mysql的decimal2double设置断点,执行select deci-”1.111″ from test会调用decimal2double将decimal和string都转化成double进行算数运算,从堆栈上看调用是按照real_op来计算的
#0 0x000000000098a3c0 in decimal2double () #1 0x00000000006724cd in Field_new_decimal::val_real() () #2 0x00000000006d36bc in Item_func_minus::real_op() () #3 0x00000000006ccf61 in Item_func_numhybrid::val_real() () #4 0x000000000068ed04 in Item::send(Protocol*, String*) () #5 0x0000000000521e58 in Protocol::send_result_set_row(List |
官方文档印证了这种想法,如果另外一个变量是decimal或者integer的时候按照decimal来进行,其他情况下都使用浮点数来进行。
那应该如何进行decimal进行计算呢,在所有计算的地方显式的使用cast进行类型转化,比如把sql写成这样,所有用到amount的地方都加上deci-cast(“1.111″ as decimal(25,2))。