SQL Server - 浮点数与 varchar
Posted
技术标签:
【中文标题】SQL Server - 浮点数与 varchar【英文标题】:SQL Server - float vs varchar 【发布时间】:2019-11-28 14:53:45 【问题描述】:在 SQL Server 中,我将十进制数据存储在表中(从不用于连接或过滤)。此十进制数据是可变的 - 80% 的时间它具有单个数字值(1、4、5),其余 20% 具有 16 位小数(0.8999999761581421、3.0999999046325684)。
我想知道是否可以使用varchar
而不是float
节省任何存储空间,或者我是否应该坚持使用float
,因为这是数字数据?
【问题讨论】:
decimal
float
。 “我有十进制数据”你真的是指“我有浮点数据”吗?如果不是,您的数据实际上是decimal
而不是float
?无论哪种方式,都不要使用varchar
来存储数字数据。
@varun 。 . .这在我看来很可疑。我猜整数是某种代码,小数是真实值——数据不应该混合在一个列中。
无论您是保留FLOAT
还是使用DECIMAL
,都不要使用字符串类型来存储数字数据,无论存储考虑如何。 唯一 可能合适的时间是,如果您非常具体地需要存储从外部系统接收到的数据完全,因为您得到它,一个字符一个字符,即使它也有数值。这显然不是其中一种情况。如果存储甚至是一个问题,您应该在数据类型之前考虑行和页面压缩之类的事情,因为混淆字符串和数字是一个巨大的痛苦来源。
【参考方案1】:
始终使用最合适的数据类型!由于这显然是 数字 数据 - 请使用数字类型。这将允许例如对值求和,按这些值排序 - 这些是数字 - 所以对待和存储它们!!
如果您需要支持分数,可以使用 FLOAT
或 REAL
,但它们因舍入错误等而臭名昭著。使用 DECIMAL(p,s)
可以避免这些陷阱 - 它稳定、精确,不易出现舍入误差。所以这将是我合乎逻辑的选择。
请参阅official MS docs for DECIMAL
,了解有关如何定义p
(精度 - 总位数)和s
(刻度 - 小数点后的位数)的详细信息.
顺便说一句:这些存储在更少字节中,而varchar
列的大小足以容纳这些值!
【讨论】:
如果此数值数据用于任何数值计算,我同意您的看法。但事实并非如此。它是科学价值之一,并按原样显示在报告中。那么,您仍然建议使用小数而不是 varchar 吗?因为我的理解是 float 会占用固定数量的字节,这与 varchar 不同。谢谢! @varun: YES!!!!!! 正如我所提到的 -decimal
很可能会使用 FEWER b> 空间而不是可比较的 varchar
- 更有理由选择 numerical 数据类型
@varun:等到你突然不得不按这些列之一对 SELECT
进行排序 - 如果你为此使用 varchar
- 祝你好运! -这只会导致无休止和不必要的悲伤和头痛 - 不要这样做。如果它看起来像一个数字,嘎嘎声像一个数字,闻起来像一个数字 - 它是一个数字,那么你应该无论如何将它处理和存储作为一个数字
【参考方案2】:
这是一个有趣的观察:
从数学值0.9
开始
将其转换为二进制数。出于同样的原因,1/3 不能用以 10 为底的有限位数表示,数字 0.9 也不能用以 2 为底的有限位数表示。确切的数学值是:
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
有没有可能你所有的输入都是简单的小数点后一位数字,已经存储为浮点值,然后转换回十进制?
【讨论】:
以上是关于SQL Server - 浮点数与 varchar的主要内容,如果未能解决你的问题,请参考以下文章