文章目录
前言
在 SQL Server 里,数值类型可简单分为精确数值类型和近似数值类型,其中近似数值也就是我们常说的浮点数。本篇文章将分别介绍SQL Server的数值类型,并且探讨为什么浮点数计算具有不准确性,最后附上SQL server数值类型在C#中相对应的名称
一、SQL Server数值类型
1.1 整数数据 bit
- 在 SQL Server 中,bit 是一种整数数据类型。主要用于存储布尔值或二进制信息,可以采用值1或 0NULL。
SQL Server 数据库引擎对位列的存储有优化处理。
从存储角度来看,每个bit 类型上只需要 1 位(bit,二进制位)就可以表示 0 或 1 这两种状态。但在计算机存储中,最小的可寻址存储单位是字节(Byte),1 字节等于 8 位。
如果表中的 bit 列为 8 列或更少,SQL Server 会将 8 个 bit 列合并存储在 1 个字节中,作为 1 个字节存储。 如果 bit 列为 9 到 16 列,则这些列作为 2 个字节存储,以此类推
- 使用场景
- 表示某种布尔状态,比如是否报警
- 表示某种配置状态,比如是否开启报警
- 补充说明
- bit类型的强制转换,当将其他数据类型的值插入 bit 列时,非零值会被转换为 1,零值会被转换为 0
CREATE TABLE AlarmInfo (
ID INT IDENTITY(1,1) PRIMARY KEY,
AlarmStatus BIT NOT NULL,
IsEnabled BIT NOT NULL DEFAULT 1
);
1.2 整数数据 tinyint、smallint、int 和 bigint
在 SQL Server 中,int、bigint、smallint 和 tinyint 都属于整数数据类型。它们的主要区别在于存储范围和存储空间占用
数据类型 | 范围 | 范围表达式 | 存储字节 |
---|---|---|---|
tinyint | 0 到 255 | 2^0 -1 到 2^8 -1 | 1 个字节 |
smallint | -32,768 到 32,767 | -2^15 到 2^15-1 | 2 个字节 |
int | -2,147,483,648 到 2,147,483,647 | -2^31 到 2^31-1 | 4 字节 |
bigint | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | -2^63 到 2^63-1 | 8 字节 |
int 数据类型是 SQL Server 中的主要整数数据类型 。 bigint 数据类型用于整数值可能超过 int 数据类型支持范围的情况 。
在数据类型优先次序表中,bigint 介于 smallmoney 和 int 之间 。
若要节省数据库空间,请使用能够可靠包含所有可能值的最小数据类型。
- 数据转换
-
CAST 函数
-- 从 tinyint 转换为 int DECLARE @tinyIntNum TINYINT = 255; SELECT CAST(@tinyIntNum AS INT) AS ConvertedToInt; -- 从 int 转换为 bigint DECLARE @intNum INT = 2147483647; SELECT CAST(@intNum AS BIGINT) AS ConvertedToBigInt;
-
CONVERT 函数
-- 从 smallint 转换为 bigint DECLARE @smallIntNum SMALLINT = 32767; SELECT CONVERT(BIGINT, @smallIntNum) AS ConvertedToBigInt;
-
- 补充说明
- 若要节省数据库空间,请使用能够可靠包含所有可能值的最小数据类型。例如, tinyint 足以满足一个人的年龄,因为没有人活在255岁以上。 但 tinyint 不足以满足建筑物的年龄,因为一栋建筑可以超过 255 岁。
1.3 ★ 浮点数据 real 和 float
float和real是SQL Server 里典型的浮点数。real和float的区别在于浮点数位数。
我们先回忆一下浮点数
1.3.1 浮点数的定义
浮点数由整数部分、小数点和小数部分组成。用科学计数法的形式来表示。以 real32 位单精度浮点数为例,它由 1 位符号位、8 位指数位和 23 位尾数位组成。符号位表示数的正负,指数位决定了数的大小范围,尾数位则表示数的精度。
1.3.2 SQL Server中的real 和 float
在 SQL Server 里,real 和 float 数据类型都属于二进制浮点数类型。
real 类型:real 的 ISO 同义词为 float(24) , real(32 位单精度浮点数)里1 位用于表示符号,8 位用于表示指数,剩下的 23 位用于表示尾数。加上隐含的前导 1(在 IEEE 754 标准中,规范化的二进制浮点数的整数部分默认是 1,不占用位),总共相当于 24 位的精度。的 ISO 同义词为 float(24) 。real 类型可以提供大约 7 位的十进制精度。
real由于总共相当于 24 位的精度,由 24 位二进制数能表示的不同组合数量有限,换算成十进制后,大约能精确表示 7 位十进制数字。也就是是如果我们用real类型存储 1234567.89, 查询结果可能不会精确显示为 1234567.89,而是一个近似值,因为 real 类型无法精确存储这么多有效数字。
float类型:floatI的SO 同义词为 float(53)。float(53)(64 位双精度浮点数)里1 位用于表示符号,11 位用于表示指数,剩下的 52 位用于表示尾数,加上隐含的前导 1,总共相当于 53 位的精度。float类型支持去手动设置精度。float(53) 类型可以提供大约 15 位的十进制精度。
1.3.3 存储空间
- real:real 类型是 float 类型的单精度版本,固定占用 4 个字节。
- float:float 类型根据指定的精度不同,占用的存储空间也不同。可以指定精度为 1 - 53 位,当精度为 1 - 24 位时,占用 4 个字节;当精度为 25 - 53 位时,占用 8 个字节。默认情况下,如果不指定精度,float 类型使用 8 个字节。
1.3.4 取值范围
数据类型 | 范围 | 存储 |
---|---|---|
real | -3.40E + 38 至 -1.18E - 38、0 以及 1.18E - 38 至 3.40E + 38 | 4 个字节 |
float | -1.79E + 308 至 -2.23E - 308、0 以及 2.23E - 308 至 1.79E + 308 | 取决于 n 的值 |
1.3.5 使用场景
float:当需要处理非常大或非常小的数值,并且对精度要求较高(需要 15 位左右十进制精度)时,建议使用 float 类型(8 字节存储)。例如,在科学计算、金融计算中处理极大或极小的数值。
real:如果对精度要求相对较低,只需要大约 7 位十进制精度,并且希望节省存储空间,那么可以使用 real 类型。例如,在一些对精度要求不是特别高的统计数据存储场景中。
1.3.6 不准确的浮点数
- 浮点数数据采用二进制来存储和处理的,而我们日常使用的是十进制数。部分十进制小数无法精确地转换为二进制小数,这就会造成精度损失。如十进制小数 0.1,转换为二进制时是一个无限循环小数 0.0001100110011…
- 在进行浮点数运算时,由于中间结果的精度可能超出了存储格式所能表示的范围,需要进行舍入操作(1.3.2 小节探讨了精度的问题)。当进行多次连续的浮点数运算时,这些误差会不断累积,导致最终结果的误差变得更大。例如在进行一系列的加法或乘法运算后,最终结果可能与精确值有较大偏差。
1.4 ★ decimal 和 numeric
decimal 和 numeric是具有固定精度和小数位数的数字数据类型。 decimal 和 numeric是同义词,可以互换使用。
固定精度和小数位数。 使用最大精度时,有效值通过 -10^38 + 1 10^38 - 1。 十进制的 ISO 同义词是 dec 和 dec(p,s)。 numeric 在功能上完全等同于 decimal 。
- decimal 类型能精确地存储十进制数,不存在二进制浮点数(像 real 和 float)那种精度损失的问题。它由一个整数部分、小数点以及小数部分构成。在定义 decimal 类型的列时,需要指定两个参数:精度(precision)和小数位数(scale)。
1.5 money 和 smallmoney
money 和 smallmoney 是 SQL Server 数据库中用于存储货币值的数据类型。这两种数据类型都能精确存储货币值,不存在像 float 和 real 这类二进制浮点数类型可能出现的精度损失问题。
- money 类型:使用 8 个字节(64 位)来存储数据
- smallmoney 类型:使用 4 个字节(32 位)存储
二、SQL Server 数值类型与对应的C#数据类型
以下总结了SQL Server 数值类型与对应的C#数据类型。
SQL Server 类型 | C# 类型 |
---|---|
bit | bool |
tinyint | byte |
smallint | short |
int | int |
bigint | long |
decimal | decimal |
real | float |
float | double |
总结
以上就是今天要讲的内容,主要介绍了 SQL Server 的数值类型,包括精确数值类型(bit、tinyint、smallint、int、bigint、decimal、numeric、money、smallmoney)和近似数值类型(real、float),阐述了各类型的存储范围、存储空间、精度、取值范围、使用场景、数据转换方法,解释了浮点数计算不准确性的原因,并给出了 SQL Server 数值类型在 C# 中相对应的数据类型名称 。