SQlite: формат столбца для метки времени Unix; Целочисленные типы - PullRequest
11 голосов
/ 06 апреля 2010

Оригинальная проблема: Каков правильный формат столбца для метки времени Unix?

Сеть полна путаницы: в некоторых публикациях утверждается, что в SQLite нет беззнаковых типов - ни за что, или за исключением 64-битного типа int (но есть (встречные) примеры, которые вызывают UNSIGNED INTEGER). Страница типов данных упоминает это только в большом примере. Он также утверждает, что есть 6-байтовое целое число, но не дает ему имя. Кажется, мои попытки использовать INTEGER в качестве 4-байтовых подписанных меток времени хранения Unix со знаком в качестве отрицательных чисел Я слышал, что некоторые системы также возвращают 64-битные метки времени. OTOH Я не слишком люблю тратить 4 байта, чтобы сохранить 1 дополнительный бит (верхний бит метки времени), и даже если мне нужно выбрать больший формат данных, я бы предпочел перейти на 6-байтовый. Я даже видел пост, в котором утверждается, что отметка времени SQLite unix имеет тип REAL ...

Полная проблема: Может ли кто-нибудь прояснить этот беспорядок?

Ответы [ 5 ]

12 голосов
/ 07 апреля 2010

Размер целого числа

Все столбцы в базах данных SQLite имеют внутреннюю переменную ширину.Формат файла хранит целые числа в 1, 2, 3, 4, 6 или 8 байтов, в зависимости от размера числа, плюс один байт в заголовке для указания размера.Таким образом, в целом даты Unix, хранящиеся в виде целых чисел, будут занимать 5 байтов до 2038-01-19 и 7 байтов после этого.

С точки зрения пользователя C API все целые числа подписаны64-разрядный.

Тип столбца

Не имеет значения, объявляете ли вы свой столбец как INTEGER, UNSIGNED INTEGER, BIGINT или как угодно. Все, что содержит «INT», имеет целочисленное сходство. И, как уже упоминалось выше, все целые числа подписаны 64-разрядными, но обычно не хранятся таким образом.

12 голосов
/ 07 апреля 2010

SQLite не имеет неподписанные типы. Это напрямую от основного автора, а также docs . Кроме того, он не имеет фиксированной ширины столбца для целых чисел; фактическая ширина на диске - это деталь реализации.

SQLite не имеет даты или времени. Однако он имеет функции даты, которые могут работать со строками ISO8601 (TEXT), числами юлианского дня (REAL) и временными метками Unix (INTEGER).

Поэтому, если вы решите сделать свое поле времени меткой времени Unix, знайте, что оно может хранить up до 64-битных целых чисел со знаком, но значения, которые вы сохраняете сейчас, должны фактически занимать 32 бита на диске, даже если исходное значение - 64-битное time_t.

0 голосов
/ 06 апреля 2010

Не могли бы вы привести пример того, что вы подразумеваете под "Похоже, мои попытки, когда INTEGER - это 4-байтовые подписанные метки времени хранения Unix со знаком в качестве отрицательных чисел."?

Если вы еще этого не сделали, я бы посоветовал читать документы SQLite для типов данных (раздел 1.2 Тип данных даты и времени) и функций даты и времени .

0 голосов
/ 06 апреля 2010

Если вы находитесь во встроенной системе, где ситуация с памятью является критической, вы можете рассмотреть вопрос о снижении точности, сдвинув 64-битное значение на несколько бит (что дает точность 2, 4, 8 ... секунд вместо 1 sec) и использование 32-битного значения для его хранения.

0 голосов
/ 06 апреля 2010

Я бы предпочел 64-битное целое число.Классический случай беззнакового 32-разрядного целого числа - с секундами, поскольку 1970-01-01 заканчивается в 2038 году. См. http://en.wikipedia.org/wiki/Unix_time и http://en.wikipedia.org/wiki/Year_2038_problem.С 64-разрядным целым числом без знака вы в безопасности

...