PostgreSQL DBA(116) - pgAdmin(Don't do this:Don't use money&serial)
no zuo no die系列,来自于pg的wiki。
这一节的内容是:不要使用money。
理由是:
money
It's a fixed-point type, implemented as a machine int, so arithmetic with it is fast. But it doesn't handle fractions of a cent (or equivalents in other currencies), it's rounding behaviour is probably not what you want.
It doesn't store a currency with the value, rather assuming that all money columns contain the currency specified by the database's lc_monetary locale setting. If you change the lc_monetary setting for any reason, all money columns will contain the wrong value. That means that if you insert '$10.00' while lc_monetary is set to 'en_US.UTF-8' the value you retrieve may be '10,00 Lei' or '¥1,000' if lc_monetary is changed.
Storing a value as a numeric, possibly with the currency being used in an adjacent column, might be better.
原因是money类型是定点类型,在计算机中通过机器int类型实现,取整行为可能不符合期望,同时该字段并没有存储货币单位,取决于数据库的lc_monetary设定,如果计量单位变化那么该值可能会存在问题,因此使用numeric存储数值额外使用其他字段存储货币单位。
[local]:5432 pg12@testdb=# drop table if exists t_money;NOTICE: table "t_money" does not exist, skippingDROP TABLETime: 35.404 ms[local]:5432 pg12@testdb=# create table t_money(id int,c1 money);CREATE TABLETime: 133.600 ms[local]:5432 pg12@testdb=# insert into t_money(id,c1) values(1,112343.01);INSERT 0 1Time: 0.929 ms[local]:5432 pg12@testdb=# insert into t_money(id,c1) values(2,112343.31234);INSERT 0 1Time: 0.640 ms[local]:5432 pg12@testdb=# insert into t_money(id,c1) values(3,112343.50);INSERT 0 1Time: 0.599 ms[local]:5432 pg12@testdb=# insert into t_money(id,c1) values(4,112343.99);INSERT 0 1Time: 0.523 ms[local]:5432 pg12@testdb=# insert into t_money(id,c1) values(5,112343.3199);INSERT 0 1Time: 0.483 ms[local]:5432 pg12@testdb=# insert into t_money(id,c1) values(6,112343.3150);INSERT 0 1Time: 0.533 ms[local]:5432 pg12@testdb=# insert into t_money(id,c1) values(7,112343.3101);INSERT 0 1Time: 0.531 ms[local]:5432 pg12@testdb=#
查询数据,实际的数据是四舍五入,保留两位小数
[local]:5432 pg12@testdb=# select * from t_money; id | c1 ----+------------- 1 | $112,343.01 2 | $112,343.31 3 | $112,343.50 4 | $112,343.99 5 | $112,343.32 6 | $112,343.32 7 | $112,343.31(7 rows)Time: 0.321 ms
修改数据库参数的货币设置为zh_CN
[local]:5432 pg12@testdb=# [local]:5432 pg12@testdb=# show lc_monetary; lc_monetary ------------- zh_CN.UTF-8(1 row)Time: 5.212 ms[local]:5432 pg12@testdb=# select * from t_money; id | c1 ----+-------------- 1 | ¥112,343.01 2 | ¥112,343.31 3 | ¥112,343.50 4 | ¥112,343.99 5 | ¥112,343.32 6 | ¥112,343.32 7 | ¥112,343.31(7 rows)Time: 2.092 ms[local]:5432 pg12@testdb=#
美钞成了人民币。
参考资料
Don't Do This