SQL 服务器如何在内部存储小数类型的值?

How does SQL Server store decimal type values internally?

在SQL服务器中,您可以使用FLOATREAL存储浮点值,其存储格式由IEEE 754标准定义。对于定点值,我们可以使用 DECIMAL 类型(它有一个同义词 NUMERIC)。但是我不太确定 SQL 服务器如何在内部存储 DECIMAL 值。例如,如果我定义一个 table 并插入这样一行:

IF OBJECT_ID('dbo.test_number_types') IS NOT NULL DROP TABLE dbo.test_number_types;
CREATE TABLE dbo.test_number_types
(
    id INT IDENTITY(1, 1),
    c1 NUMERIC(5, 4)
)
GO

INSERT INTO dbo.test_number_types(c1)VALUES(5.7456);

当我使用 DBCC PAGE 命令检查 SQL 服务器如何存储数字 5.7456 时,我得到了这个:

01 70 E0 00 00

这个十六进制字符串应该使用小端。我无法弄清楚 SQL 服务器如何将 5.7456 变成 01 70 E0 00 00 以及它如何决定整数部分有多少字节以及小数部分有多少字节。有人可以帮忙吗?


顺便说一句,我已经查看了这本书 "SQL Server 2012 Internals"。有一章专门介绍数据类型存储。不过书上好像没有提到DECIMAL类型的存储。

Martin 的 Smith 评论为您提供了线索。 SQL 服务器不使用 BCD。 它将数据存储为一个整数,没有小数位(它可以这样做,因为小数位存储在列的元数据中)。所以 5.7456 存储为 57456,或 0xE070。在 SQL 臭名昭著的字节交换之后,它被转换为 70 E0 00 00.

开头的01是符号。 01用于正数; 00 表示否定。

(但是,我必须问 - 你为什么需要这个?在典型的使用中,你永远不需要理会 SQL 服务器的内部结构)