如何"钱"和"十进制" SQL Server中的数据类型存储在内存中?

时间:2013-10-22 18:43:27

标签: sql sql-server memory

我想知道内存中的存储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 或存储特定日期的天数?

3 个答案:

答案 0 :(得分:10)

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

单个byte由8个bits组成。 bit可以包含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和s​​mallmoney值,就像其他所有内容一样。如果您需要更多信息,请阅读http://computer.howstuffworks.com/bytes.htm

或者您可能会看到这个可能的金钱范围和小额金额: http://technet.microsoft.com/en-us/library/ms179882.aspx

<强>更新
对于DATETIME数据类型,它是相同的概念,稍微扭曲一下。在MS SQL中,使用2个数字存储DATETIME。第一个是自19/1年1月1日以来的天数,第二个是自午夜以来的刻度数: 看到 http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/how-are-dates-stored-in-sql-serverWhen storing a datetime in sql server (datetime type), what format does it store it in?

答案 1 :(得分:3)

  

如何存储SQL Server中的“money”[...]数据类型   存储器?

如果您想查看如何存储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。

答案 2 :(得分:1)

我想你可能会发现这个有趣Performance / Storage Comparisons : MONEY vs. DECIMAL

  

为MONEY辩护的人显示了MONEY使用的空间   存储在DECIMAL(20,4)列中的相同信息。 不是全部   令人惊讶的是,后者略大。但是就是这样   整个故事?不,有两个原因。一个是性能   没有比较这些选择,另一个是DECIMAL(20,4)   存储货币数据不是一个非常现实的要求。的除非   您正在存储豪华游艇或飞机的定价信息   运营商,在这种情况下,您可以删除小数位   完全使用INT或BIGINT。对于我们其他人来说,这是一个更好的选择   将是DECIMAL(8,2)或DECIMAL(10,2)。

另请查看以下相关问题:Should you choose the MONEY or DECIMAL(x,y) datatypes in SQL Server?