数据库教程27:SQL Server中的数字类型,如real、float、decimal、numeric、money等及各自区别

1,200 阅读4分钟

这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战

数字数据类型包括,

  • 用于保存小数浮点数real型、float型;
  • 用于精确保存数值的decimal型、numeric型;
  • 代表货币值的money/smallmoney;
  • 用于保存整数的int、bigint、smallint、tinyint;
  • 取值为1、0或NULL的整型bit,常用来表示逻辑true或false。

关于浮点数

在SQL Server中浮点数值的数据采用上舍入(Round up)的方式进行存储。因为浮点数是近似值,因此有时无法精确的表示数值。

向上舍入就是,要舍入的小数部分不论其大小,只要是一个非零的数,就要在该数字的最低有效位上加1,并进行必要的进位。

real、float、decimal、numeric的区别

数据类型描述存储
real从-3.40E+38到3.40E+38的浮动精度数字数据4字节
float(n)从-1.79E+308到1.79E+308的浮动精度数字数据。参数n指示该字段保存4字节还是8字节。float(24)保存4字节,而float(53)保存8字节。默认值为53.4或8字节
decimal(p,s)
numeric(p,s)
固定精度和比例的数字。允许从1038+1-10^{38}+11038110^{38}-1之间的数字。p参数指定可以存储的最大位数(小数点左侧和右侧)。p必须是1到38之间的值,默认值是18。s参数指定小数点右侧存储的最大位数。s必须是0到p之间的值,默认是0。5-17字节
  • decimalnumeric:两者同义,可以互换使用,用于精确存储数值
  • float 和 real:用于表示浮点数值数据的大致数值数据类型。浮点数据为近似值,不能精确存储数值。 real的同义词为 float(24)

decimal(numeric)示例

CREATE TABLE dbo.MyTable  
(  
  MyDecimalColumn DECIMAL(5,2),
  MyNumericColumn NUMERIC(10,5)
);  

INSERT INTO dbo.MyTable VALUES (123, 12345.12),(12, 1234.12); 

SELECT MyDecimalColumn, MyNumericColumn FROM dbo.MyTable; 

结果如下:

MyDecimalColumn  MyNumericColumn
123.00	            12345.12000
12.00	            1234.12000

decimal类型将精度和小数位数的每个特定组合看作是不同的数据类型。例如,decimal(5,5) 和 decimal(5,0) 被当作不同的数据类型。

关于real、float逻辑比较

由于real和float是近似值,大多数指定的值就是存储的近似值。

由于近似特性,在财务应用程序、等值核对、舍入操作等需要精确数值的场合,应使用 integer、decimal、money 或 smallmoney 数据类型。

在 WHERE 子句搜索条件中,使用 =<> 运算符应避免应用在float 列或 real 列。float 列和 real 列最好只限于 > 比较或 < 比较。

IEEE754规范提供四种舍入模式:舍入到最近、向上舍入、向下舍入以及舍入到零。

所有的数值都必须精确到确定的精度,但会产生微小的浮点值差异。因为浮点数字的二进制表示法可以采用很多合法舍入规则中的任意一条,因此我们不可能可靠地量化浮点值.

money 和 smallmoney

代表货币或货币值的数据类型。

money 和 smallmoney 数据类型精确到它们所代表的货币单位的万分之一。 对于 Informatica,money 和 smallmoney 数据类型精确到它们所代表的货币单位的百分之一。

数据类型范围存储
money-922,337,203,685,477.5808 到 922,337,203,685,477.5807(对于 Informatica,为 -922,337,203,685,477.58 到 922,337,203,685,477.58。 Informatica 仅支持两位小数,而不是四位。)8个字节
smallmoney-214,748.3648 到 214,748.36474个字节

int、bigint、smallint 和 tinyint

使用整数数据的精确数字数据类型。若要节省数据库空间,请使用能够可靠包含所有可能值的最小数据类型。

例如,对于一个人的年龄,tinyint 就足够了,因为没人活到 255 岁以上。 但对于建筑物的年龄,tinyint 就不再适应,因为建筑物的年龄可能超过 255 年。

数据类型范围存储
bigint-2^63 (-9,223,372,036,854,775,808) 到 2^63-1 (9,223,372,036,854,775,807)8字节
int-2^31 (-2,147,483,648) 到 2^31-1 (2,147,483,647)4个字节
smallint-2^15 (-32,768) 到 2^15-1 (32,767)2字节
tinyint0 到 2551字节

大于 2,147,483,647 的整数常量将转换为 decimal 数据类型,而不是 bigint 数据类型。 下面的示例显示当超过此阈值时,结果的数据类型将从 int 变为 decimal 。

SELECT 2147483647 / 2 AS Result1, 2147483649 / 2 AS Result2 ;  

结果:

Result1      Result2  
1073741823   1073741824.500000