SQL Server如何在内部存储十进制类型值?

时间:2016-12-18 03:13:40

标签: sql-server storage numeric internals

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

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 Server如何存储数字5.7456时,我得到了这个:

01 70 E0 00 00

这个十六进制字符串应该使用little endian。我无法弄清楚SQL Server如何将5.7456转换为01 70 E0 00 00以及它如何确定积分部分的字节数以及小数部分的字节数。有人可以帮忙吗?

顺便说一下,我查了一下“SQL Server 2012 Internals”这本书。有一章专门介绍数据类型。但似乎书中没有提到DECIMAL类型存储。

1 个答案:

答案 0 :(得分:8)

马丁的史密斯评论为您提供了线索。 SQL Server不使用BCD。 它将数据存储为整数,不带小数位(由于小数位存储在列的元数据中,因此可以执行此操作)。因此5.7456存储为574560xE070。在SQL臭名昭着的字节交换之后,这将转换为70 E0 00 00

领先的01是标志。 01用于正数; 00表示否定。

(但是,我必须问 - 你为什么需要这个?在典型的使用中,你永远不需要打扰SQL Server的内部)