6

使用 SQL Server 2008 R2,SP2文档datetime2需要 6、7 或 8 个字节,具体取决于您使用的女巫精度

我需要以二进制形式(连接值)存储大量数据,并且我喜欢每个日期时间仅使用 6 个字节的想法,但是当我尝试时:

declare @_dt_p0 datetime2(0) = '2012-05-18 11:22:33'
select  CONVERT(varbinary, @_dt_p0), LEN(CONVERT(varbinary, @_dt_p0))

declare @_dt_p4 datetime2(4) = '2012-05-18 11:22:33'
select  CONVERT(varbinary, @_dt_p4), LEN(CONVERT(varbinary, @_dt_p4))

declare @_dt_p7 datetime2(7) = '2012-05-18 11:22:33'
select  CONVERT(varbinary, @_dt_p7), LEN(CONVERT(varbinary, @_dt_p7))

它显然需要一个额外的字节,我做错了什么?

4

2 回答 2

10

我想我无法解释为什么 varbinary 转换的长度/数据长度是 7 而不是 6(Mikael 后来发现转换为 varbinary 将精度添加为额外的字节),但我不知道为什么你认为那是无论如何,一个有效的测试。我可以确认,当您使用实际列时,页面上存储了 6 个字节(尽管该行的空开销会有所不同,具体取决于该列是否可为空)。我怎样才能证明这一点?

USE tempdb;
GO

CREATE TABLE dbo.x
(
 d1 DATETIME2(0)  NULL, 
 v1 VARBINARY(32) NULL,
 d2 DATETIME2(0)  NOT NULL, 
 v2 VARBINARY(32) NOT NULL
);

declare @d datetime2(0) = '2012-05-18 11:22:33';

INSERT dbo.x(d1, v1, d2, v2)
SELECT @d, CONVERT(VARBINARY(32), @d), @d, CONVERT(VARBINARY(32), @d);

SELECT DATALENGTH(d1), DATALENGTH(v1), 
       DATALENGTH(d2), DATALENGTH(v2) FROM dbo.x;

结果:

6    7    6    7

因此,datetime2 列是 6 个字节,但 varbinary 列是 7 个字节。不管是否为空。我们可以通过实际检查页面来仔细观察。让我们在堆中查找该表的所有页面:

DBCC IND('tempdb', 'dbo.x', 0);

我的系统上的部分结果(你的会有所不同):

PagePID  PageType
283      10
311      1

所以现在让我们看一下第 311 页:

DBCC TRACEON(3604, -1);
DBCC PAGE(2, 1, 311, 3);

我们可以看到 datetime2 列确实在页面上占据了 6 个字节:

Slot 0 Column 1 Offset 0x4 Length 6 Length (physical) 6

d1 = 2012-05-18 11:22:33            

v1 = [Binary data] Slot 0 Column 2 Offset 0x19 Length 7 Length (physical) 7
v1 = 0x00f99f00b0350b               

Slot 0 Column 3 Offset 0xa Length 6 Length (physical) 6

d2 = 2012-05-18 11:22:33            

v2 = [Binary data] Slot 0 Column 4 Offset 0x20 Length 7 Length (physical) 7
v2 = 0x00f99f00b0350b              
于 2012-08-21T19:20:41.570 回答
1

再会,

首先我想说这是最好的问题:“我不知道你为什么认为这是一个有效的测试”,因为答案是这不是有效的测试

您可以阅读有关该问题的所有内容,包括对 DateTime2 实际存储格式的说明,以及为什么检查“CONVERT to binary”的结果并假设这与实际存储的数据相同是错误的!它在 varchar 或 nvarchar 等可变长度数据中不准确,在 DateTime2 中也不准确。检查和获取真实存储格式的唯一方法是使用 DBCC PAGE 检查数据本身。 http://ariely.info/Blog/tabid/83/EntryId/162/Examine-how-DateTime2-type-stored-in-the-data-file.aspx

我希望这很有用:-)

于 2015-05-10T08:46:22.990 回答