为什么postgreSQL将十进制字段存储为BigDecimal哈希?

AnA*_*ice 4 postgresql ruby-on-rails ruby-on-rails-3

我在rails3/postgreSQL中有以下模型/表:

create_table "admin_reports", :force => true do |t|
  t.string   "report"
  t.decimal  "result"
  t.string   "result_type"
  t.datetime "created_at"
  t.datetime "updated_at"
end
Run Code Online (Sandbox Code Playgroud)

在生产时,AdminReports.result不存储小数,而是存储哈希:

AdminReport.last

=> #<AdminReport id: 4, report: "dau", result: #<BigDecimal:cbca0f0,'0.8E1',4(8)>, result_type: "percentage", created_at: "2012-02-28 22:05:15", updated_at: "2012-02-28 22:05:15">
Run Code Online (Sandbox Code Playgroud)

我希望看到的地方:

AdminReport.last

=> #<AdminReport id: 4, report: "dau", result: 10.10, result_type: "percentage", created_at: "2012-02-28 22:05:15", updated_at: "2012-02-28 22:05:15">
Run Code Online (Sandbox Code Playgroud)

在rails控制台中,即使我尝试手动设置结果字段,如下所示:

@a = AdminReport.last
@a.result = 8.89
@a.save
Run Code Online (Sandbox Code Playgroud)

它仍然将AdminReport.result显示为BigDecimal哈希.有什么想法在这里发生了什么?

谢谢

mu *_*ort 6

您使用的是十进制列:

create_table "admin_reports", :force => true do |t|
  #...
  t.decimal  "result"
  #...
end
Run Code Online (Sandbox Code Playgroud)

这通常意味着您要使用固定数量的小数位,因此您可能还想指定:precision:scale选项.当ActiveRecord看到一个十进制列时,它会将值转换为Ruby的BigDecimal,这样您就可以在Ruby-land中保持所需的小数位数; 如果AR使用浮点值,那么你会遇到所有常见的浮点问题,你可能最终将一个值从数据库中拉出来并放回另一个值而不是故意改变它,使用BigDecimal完全避免了这个问题.

当你看到这个:

#<BigDecimal:cbca0f0,'0.8E1',4(8)>
Run Code Online (Sandbox Code Playgroud)

您只是看到了inspectBigDecimal 的标准输出.如果你使用to_s(或"#{...}"),你会看到更熟悉的东西.

所以没什么好担心的.如果你需要使用非整数运算但不想要浮点的所有问题,那么十进制列(带:precision:scale)是正确的选择.