在Doctrine 2中,指定十进制字段类型时,“scale”和“precision”是什么意思?

82

我正在为我的Symfony2应用程序在Doctrine2中创建一个十进制字段,以容纳财务数据。

目前,它看起来像这样:

/**
 * @ORM\Column(type="decimal")
 */
protected $rate;

当我输入一个值并且该值被持久化到数据库时,它被舍入为整数。我猜想我需要为该字段设置精度和比例类型,但我需要有人准确地解释一下它们的作用是什么?

Doctrine2文档说:

precision:十进制(精确数字)列的精度(仅适用于十进制列)

scale:十进制(精确数字)列的比例(仅适用于十进制列)

但这并没有告诉我太多。

我猜想精度是要四舍五入到的小数位数,所以我认为应该是2,但什么是比例?比例是有效数字吗?

我的字段声明应该是这个吗? :-

/**
 * @ORM\Column(type="decimal", precision=2, scale=4)
 */
protected $rate;
6个回答

126

Doctrine使用类似于SQL类型的类型。Decimal恰好是一种固定精度类型(不像浮点数)。

MySQL文档中引用:

在DECIMAL列声明中,可以(通常也会)指定精度和比例;例如:

salary DECIMAL(5,2)

在这个例子中,5是精度,2是比例。精度表示存储值的有效数字个数,比例表示小数点后可存储的数字个数。

标准SQL要求DECIMAL(5,2)能够存储具有五个数字和两个小数点的任何值,因此可以存储在salary列中的值范围从-999.99到999.99。


33

简短说明:我必须从属性precision和scale中移除引号,如下所示:

@ORM\Column(type="decimal", precision=8, scale=2)

27
@Column(type="decimal", precision=5, scale=2) means 123.45

如果您将1.20存储在精度为5、比例为2的字段中会发生什么?或者精度=5是一个最大值吗? - Jos

0
正如@Waldemar所说,只需使用整数/字符串以分为单位存储价格,并使用Money库来管理它,因为您需要将100分/3人进行分割,而Money库具有安全执行此操作的方法。

0
我知道这篇文章很老,但是为什么程序员们还在使用十进制呢...只需使用64位整数,并将其定义为分(或千),而不是整数。一切都从那里变得简单了。
例如,不要存储123.45,而是存储12345,在整数上进行所有计算,需要时将值呈现给用户为123.45。
顺便说一句,至少目前没有人拥有2305843009213693952分或23,058,430,092,136,939.52个整数。

如果你需要给某人某物的x%,你只需像手动计算一样计算它-> x%= x/100 ->(x * value)/ 100 - Waldemar
唯一的问题可能是处理舍入误差,但使用十进制也会遇到同样的问题。 - Waldemar
我很好奇,如果大银行有一个像美国这样拥有数万亿的客户,他们会怎么做? - Waldemar
他们使用bigint,我猜。或者将精度增加到最高限制或其他什么东西。 - fafa.mnzm
在银行案例中,他们可能会将值存储为字符串,并在其编程中使用特殊类将字符串分成整数组进行单独的数学计算,就像学校数学一样。主要区别在于,在类似银行的编程中,您不处理单个数字,而是处理数字块(这意味着计算模最大整数大小而不是模10)。 - Heiko Vogel
显示剩余2条评论

0
 * @ORM\Column(type="decimal", precision=10, scale=2)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接