使用SQL Server 2008 R2,SP2 docs表示 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))
显然需要一个额外的字节,我做错了什么?
答案 0 :(得分:10)
我认为我不能解释为什么varbinary转换的长度/数据长度是7而不是6(Mikael后来发现the convert to varbinary adds the precision as an extra byte),但我不知道为什么你认为这是一个有效的测试无论如何。当您使用实际列时,我可以确认页面上存储了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
现在让我们看一下Page 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
答案 1 :(得分:1)
美好的一天,
首先,我想说这是最好的问题:"我不知道为什么你认为这是一个有效的测试",因为答案是这个是无效的测试!
您可以阅读有关该问题的所有信息,包括DateTime2实际存储格式的解释,以及为什么错误地检查" CONVERT到二进制"的结果。并假设这与实际存储的数据相同!它在varchar或nvarchar等可变长度数据中并不准确,并且在DateTime2中也不准确。检查和获取真实存储格式的唯一方法是使用DBCC PAGE检查数据本身。 http://ariely.info/Blog/tabid/83/EntryId/162/Examine-how-DateTime2-type-stored-in-the-data-file.aspx
我希望这很有用: - )