2013-10-22 61 views
8

我想知道存儲器中的存儲SQL Server數據類型。SQL Server中的「money」和「decimal」數據類型如何存儲在內存中?

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 或存儲了特定日期的天數?

+0

它是**不**存儲在一個字符串(字符)形式。請確認你知道這一點。 –

+0

你關心內存存儲而不是數據文件嗎? – StingyJack

+0

是的!我知道它沒有存儲在char中。 – Nooshin

回答

10

只是平添幾分這裏...

byte是由8 bits。 A bit可以保存2個值(0或1)。

所以4個字節是32位(4×8)。這意味着可以存儲的數值範圍是從0到2^32,這總共給出了4,294,967,296個值。

smallmoney被簽名,所以我們放下一個要用於符號的位,這會留下2^31或2,147,483,648個可能值和+/-符號。

現在我們考慮到貨幣類型的最後4位數字是始終在小數點後,我們結束了以214,748.3647一系列-214,748.3648

技術上,錢和smallmoney值由翻轉存儲與其他所有內容一樣,字或字節中的位。如果您需要更多的信息,請閱讀http://computer.howstuffworks.com/bytes.htm

或者,你可能會看到這樣的金錢和smallmoney可能值範圍: http://technet.microsoft.com/en-us/library/ms179882.aspx

更新
對於DATETIME數據類型,這是同樣的概念用有點扭曲。在MS SQL中,使用2個數字存儲DATETIME。首先是天數,因爲1/1/1900,第二個是蜱蟲的數量從午夜開始: 見 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?

+0

非常感謝!我認爲我明白了。那麼「日期」呢?你知道它是如何存儲的? – Nooshin

+0

@ user2908422:查看更新 – NotMe

+0

對於您的更新,您應該提及'datetime',而不是'date'。自2008年發佈以來,SQL Server具有特定的'date'數據類型,它當然*不*存儲時間組件。 –

1

我想你可能會發現這個有趣的Performance/Storage Comparisons : MONEY vs. DECIMAL

的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?

+0

謝謝你的回答,但我並不擔心性能和存儲空間。我想知道「它是如何存儲在內存中的?」 – Nooshin

+0

我不是100%確定,但我認爲它將以與Decimal值存儲類似的方式進行存儲。 http://en.wikipedia.org/wiki/Binary-coded_decimal :) –

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。

相關問題