Почему тип datetime в SQL Server Compact округляет значения?

Я столкнулся с чем-то, что меня удивило.

Я использую WinPcap для сбора данных из сети. Внутри WinPcap использует счетчики производительности Windows для создания временных меток. Я знаю, что они подвержены дрейфу, но эти метки времени, тем не менее, имеют точность до микросекундного уровня.

Если я вставлю эти метки времени в базу данных SQL Server Compact 4.0 как значение datetime и извлеку их позже, то замечу, что точность упала до миллисекунд.

Например,

10:52:19.706084 -> 10:52:19.706000

С тех пор я прочитал здесь что SQL Server округляет значения с типом datetime до 0,000, 0,003 или 0,007 миллисекунды. Это объясняет, что происходит.

Теперь поле datetime использует 8 байтов для хранения своих данных, 4 байта для даты и 4 миллисекунды с полуночи. Но если я вызову DateTime.ToBinary(), я верну 8-байтовое число, представляющее значение со всей его точностью. На самом деле, если я запишу это значение в базу данных в столбце bigint, а затем вызову DateTime.FromBinary() при извлечении этого значения, я получу исходное значение с той же точностью.

Это подход, который я собираюсь использовать, но мне все еще любопытно: почему исходный тип datetime в SQL Server Compact не использовал механизм хранения ToBinary/FromBinary DateTime?

ИЗМЕНИТЬ:

Как справедливо отмечает Аарон Бертран, SQL Compact не поддерживает datetime2. Кроме того, datetime2 использует 6, 7 или 8 байтов, а не 54 байта в обычном SQL Server. Однако мой основной вопрос остается в силе.


person Matt Davis    schedule 01.08.2013    source источник
comment
Это может помочь: stackoverflow.com/questions/12729972/   -  person Aaron Bertrand    schedule 01.08.2013
comment
Также я не думаю, что Compact поддерживает datetime2. А в обычном SQL Server он уж точно не занимает 54 байта (скорее 6, 7 или 8 байт). Можете ли вы привести официальный источник этого бита nvarchar(27)?   -  person Aaron Bertrand    schedule 01.08.2013
comment
Оглядываясь назад, я думаю, что вы правы по обоим пунктам. Вот где я искал, но, видимо, недостаточно близко...msdn.microsoft.com/en-us/library/bb677335(v=sql.100).aspx   -  person Matt Davis    schedule 01.08.2013
comment
Да, это длина строкового представления, а не размер хранилища.   -  person Aaron Bertrand    schedule 01.08.2013
comment
Я обновил вопрос, чтобы быть более точным в том, что я спрашиваю. Это больше любопытство, чем что-либо. Я был просто удивлен, что вставка метки времени в базу данных привела к потере данных. И я не понимаю, когда структура DateTime может кодировать/декодировать себя в 8 байтах и ​​поддерживать точность.   -  person Matt Davis    schedule 01.08.2013
comment
Это также может помочь: stackoverflow.com/questions/1143259/   -  person Aaron Bertrand    schedule 01.08.2013
comment
Я не уверен, почему они выбрали механизм хранения 4+4 для datetime, но, по крайней мере, они исправили его с помощью datetime2 (даже если они выбрали ужасное имя). Возможно, вы могли бы рассмотреть возможность использования SQL Server 2012 LocalDB вместо Compact, тогда вы не будете ограничены постоянной игрой Compact в догонялки...   -  person Aaron Bertrand    schedule 01.08.2013
comment
Принятый ответ по предоставленной вами ссылке SO содержит ссылку на довольно подробную запись о типе DATETIME. Беглый взгляд заставляет меня думать, что формат 4+4 был выбран, чтобы облегчить запросы, основанные на времени. По крайней мере, мне это кажется правдоподобным. Можете ли вы предоставить более подробную информацию об опции «LocalDB»? Он портативный, как Compact?   -  person Matt Davis    schedule 01.08.2013
comment
да, все время выполнения составляет 33 МБ. Я написал длинную статью о здесь, а официальная документация начинается здесь.   -  person Aaron Bertrand    schedule 01.08.2013


Ответы (1)


Я не знаю всех внутренних деталей или мотивации выбора, но datetime хранится внутри как, по сути, два 4-байтовых целых числа. Один представляет дату, другой представляет время. Я подозреваю, что вы теряете некоторую точность в последнем из-за того, как обрабатывались тики/миллисекунды с самых первых версий SQL Server, но опять же, я не знаю деталей низкоуровневой реализации.

Связанные вопросы для получения дополнительной справочной информации:

Каково внутреннее представление datetime на сервере sql?< /а>

Разрешить Entity Framework 4.5 использовать datetime2 с SQL Server CE4

Чтобы поддерживать необходимую точность без перемещения значения в двоичный формат и из него, я бы предложил использовать LocalDB, который обладает теми же преимуществами переносимости, что и Compact, но без многих функциональных ограничений (таких как поддержка более точного типа datetime2, в чем я уверяю вы занимаете 6-8 байт, а не 54 :-)).

person Aaron Bertrand    schedule 01.08.2013
comment
Аарон, большое спасибо за помощь. Это очень ценится. - person Matt Davis; 01.08.2013