在SQL Server中,我将十进制数据存储在表中(该数据从未用于联接或过滤)。此十进制数据是可变的-80%的时间中它具有一位数字值(1、4、5),其余20%的时间具有16位十进制数字(0.8999999761581421,3.0999999046325684)。
我想知道是否可以节省varchar
而不是float
的存储空间,还是应该坚持使用float
,因为这是数字数据?
答案 0 :(得分:2)
始终使用最合适的数据类型!由于这显然是数字数据-请使用数字类型。这将允许例如对这些值求和,并按这些值的顺序排序-这些是数字-因此请按原样对待并存储它们!
如果需要支持小数,可以 使用FLOAT
或REAL
,但是由于四舍五入等原因而臭名昭著。使用DECIMAL(p,s)
可以避免这些陷阱-它稳定,精确,不容易出现舍入错误。因此,这将是我的合理选择。
有关如何定义p
(精度-总体数字总数)和s
(小数位数-后的数字位数)的详细信息,请参见official MS docs for DECIMAL
小数点)。
还有,顺便说一句:这些存储在更少个字节中,因此varchar
列足够大,可以容纳这些值!
答案 1 :(得分:2)
这是一个有趣的发现:
从数学值0.9
将其转换为二进制数。出于同样的原因,不能以10为底的有限位数表示1/3,不能以2为底的有限位数表示0.9。精确的数学值为:
0.1 1100 1100 1100 1100 1100 1100 1100
...永远重复“ 1100”。
让我们将此值存储在IEEE-754单精度浮点值中。 (在SQL Server中,这称为REAL
类型)。为此,我们必须舍入到23个有效位。结果是:
0.1 1100 1100 1100 1100 1100 11
将其转换为与之完全相同的十进制数,就会得到:
0.89999997615814208984375
将其四舍五入到小数点后16位。您会得到:
0.8999999761581421
恰好是您作为示例显示的值。
如果您对3.1
做同样的事情,则会得到3.0999999046325684
是否所有输入都只是小数点后一位数字,这些数字已存储为浮点值,然后又转换回十进制?