9

我想了解内存中的存储 SQL Server 数据类型。

SQL Server 中的数据类型是如何money存储在内存中的?我知道它money存储在 8 个字节中,并且smallmoney存储在 4 个字节中。但我不知道怎么做?

例如,当您有 123400.93 的钱时,它是如何存储在 8 个字节中的?

我对decimalDATE数据类型有同样的问题。

尤其是DATE,格式是YYYY-MM-DD,但是3个字节是怎么存储的呢?它是按照此处所述存储:http: //dev.mysql.com/doc/internals/en/date-and-time-data-type-representation.html 还是存储特定日期的天数?

4

3 回答 3

10

只是在这里添加一点...

单曲byte由 8 组成bits。Abit可以保存 2 个值(0 或 1)。

所以 4 个字节是 32 位(4 x 8)。这意味着可以存储的数字范围是从 0 到 2^32,总共有 4,294,967,296 个值。

smallmoney是有符号的,因此我们删除要用于符号的位之一,留下 2^31 或 2,147,483,648 个可能值和 +/- 符号。

现在我们考虑到货币类型的最后 4 位总是在小数点之后,我们最终得到的范围是 -214,748.3648 到 214,748.3647

从技术上讲,money 和 smallmoney 的值是通过翻转一个字或字节中的位来存储的,就像其他所有东西一样。如果您需要更多信息,请阅读http://computer.howstuffworks.com/bytes.htm

或者您可能会看到金钱和 smallmoney 的可能价值范围: http ://technet.microsoft.com/en-us/library/ms179882.aspx

更新
对于DATETIME数据类型,它是相同的概念,但略有不同。在 MS SQLDATETIME中,a 使用 2 个数字存储。第一个是自 1900 年 1 月 1 日以来的天数,第二个是自午夜以来的刻度数:请参阅 http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/how-are-dates-stored-in -sql-server在sql server(datetime类型)中存储日期时间时,它以什么格式存储?

于 2013-10-22T19:09:33.227 回答
3

SQL Server 中的“金钱”[...] 数据类型如何存储在内存中?

如果您想查看如何存储 MONEY(8 字节)值,则可以执行以下脚本步骤/步骤:

CREATE DATABASE TestMoneyDT;
GO
USE TestMoneyDT;
GO

CREATE TABLE dbo.MyMoney -- :-)
(
    Col1 CHAR(5) NOT NULL,
    Col2 MONEY NOT NULL,
    Col3 CHAR(5) NOT NULL
);
GO

INSERT dbo.MyMoney (Col1, Col2, Col3)
VALUES ('AAAAA',12345678.0009,'BBBBB');
GO

-- Install http://www.sqlskills.com/blogs/paul/inside-the-storage-engine-sp_allocationmetadata-putting-undocumented-system-catalog-views-to-work/
EXEC sp_AllocationMetadata 'dbo.MyMoney'
GO
/*
Stored procedure output:

Object Name Index ID Alloc Unit ID     Alloc Unit Type First Page Root Page First IAM Page
----------- -------- ----------------- --------------- ---------- --------- --------------
MyMoney     0        72057594039697408 IN_ROW_DATA     (1:147)    (0:0)     (1:150)
*/

SELECT DB_ID() AS DBID
GO
/*
DBID
----
13
*/

-- Reading data from page (1:147) (file id 1, page number 147)
DBCC TRACEON(3604);         -- http://technet.microsoft.com/en-us/library/ms187329.aspx
DBCC PAGE(13, 1, 147, 3);   -- http://blogs.msdn.com/b/sqlserverstorageengine/archive/2006/06/10/625659.aspx
DBCC TRACEOFF(3604);        -- http://technet.microsoft.com/en-us/library/ms174401.aspx
GO

-- See [Memory dump @0x0000000014AEA060] of DBCC PAGE output
/*
Memory Dump @0x000000000E76A060

0000000000000000:   10001600 41414141 41e9f698 be1c0000 †....AAAAAéö.¾... 
0000000000000010:   00424242 42420300 00†††††††††††††††††.BBBBB...  

41414141 41 = AAAAA <- Col1 CHAR(5)
e9f698 be1c0000     <- Col2 MONEY take this string and run following script (look at SumOverAll values)
424242 4242 = BBBBB <- Col3 CHAR(5)
*/
GO

DECLARE @HexString VARBINARY(8) = 0xE9F698BE1C; -- One MONEY value consumes 8 bytes
WITH N10
AS 
(
    SELECT  *
    FROM    (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)) x(Num)
)
SELECT  src.*, 
        SUM(src.IntValueMultipliedByte) OVER() AS SumOverAll
FROM
(
    SELECT  n.Num, 
            SUBSTRING(@HexString, n.Num, 2) AS HexValue,
            CONVERT(INT, SUBSTRING(@HexString, n.Num, 1)) AS IntValue,
            POWER(CONVERT(NUMERIC(38,0), 256), n.Num-1) AS Byte,
            CONVERT(INT, SUBSTRING(@HexString, n.Num, 1)) * POWER(CONVERT(NUMERIC(38,0), 256), n.Num-1) AS IntValueMultipliedByte
    FROM    N10 n
    WHERE   n.Num <= LEN(@HexString)
) src;
GO

/*
NumHexValue IntValue    Byte       IntValueMultipliedByte SumOverAll
----------- ----------- ---------- ---------------------- ------------
1  0xE9F6   233         1          233                    123456780009
2  0xF698   246         256        62976                  123456780009
3  0x98BE   152         65536      9961472                123456780009
4  0xBE1C   190         16777216   3187671040             123456780009
5  0x1C     28          4294967296 120259084288           123456780009
*/

注意:我使用的是 SQL2008R2。

于 2013-10-22T20:45:31.490 回答
1

我想你可能会发现这个有趣的性能/存储比较:MONEY vs. DECIMAL

为 MONEY 争论的人显示了 MONEY 使用的空间与存储在 DECIMAL(20,4) 列中的相同信息的比较。 毫不奇怪,后者稍大一些。 但这就是故事的全部吗?不,有两个原因。一是没有比较这些选择的性能,二是DECIMAL(20,4)对于存储货币数据并不是很现实的要求。 除非您要存储豪华游艇或航空母舰的定价信息,在这种情况下,您可以完全去掉小数位并使用 INT 或 BIGINT。 对于我们其他人来说,更好的选择是 DECIMAL(8,2) 或 DECIMAL(10,2)。

还要检查这个相关问题:您应该在 SQL Server 中选择 MONEY 还是 DECIMAL(x,y) 数据类型?

于 2013-10-22T18:49:32.427 回答