我遇到了让我感到惊讶的事情。
我正在使用WinPcap
从网络收集数据。在内部,WinPcap
使用Windows性能计数器生成其时间戳。我知道它们会受到漂移的影响,但是这些时间戳的精度可以达到微秒级。
如果我将这些时间戳作为datetime
值插入SQL Server Compact 4.0数据库并稍后提取,我注意到精度已降至毫秒。
例如,
10:52:19.706084 -> 10:52:19.706000
现在,我已阅读here,SQL Server将datetime
类型的值舍入为.000,.003或.007毫秒。这解释了发生了什么。
现在,datetime
字段使用8个字节来存储其数据,4个字节用于日期,4个字节用于自午夜以来的毫秒数。但是如果我调用DateTime.ToBinary()
,我会得到一个8字节的数字,表示其所有精度的值。实际上,如果我将此值写入bigint
列中的数据库,然后在提取该值时调用DateTime.FromBinary()
,则会获得具有相同精度的原始值。
这是我将要使用的方法,但我仍然很好奇:为什么SQL Server Compact中的原始datetime
类型不使用DateTime
的ToBinary / FromBinary存储机制?
修改
正如Aaron Bertrand正确指出的那样,SQL Compact不支持datetime2
。此外,datetime2
在常规SQL Server中使用6,7或8个字节,而不是54个字节。不过,我的基本问题仍然存在。
答案 0 :(得分:2)
我不知道完整的内部细节或选择背后的动机,但datetime
内部存储为 - 基本上 - 两个4字节整数。一个代表日期,另一个代表时间。我怀疑你在后者中失去了一些精确性,因为自SQL Server的第一个版本以来已经处理了滴答/毫秒,但同样,我不知道低级实现细节。
更多背景信息的相关问题:
What is the internal representation of datetime in sql server?
Allow Entity Framework 4.5 to use datetime2 with SQL Server CE4
为了支持您想要的精度而不将值移入和移出二进制格式,我建议使用LocalDB,它具有与Compact相同的可移植性优势,但没有很多功能限制(例如支持)对于更精确的datetime2
类型 - 我保证你需要6-8个字节,而不是54: - ))。