12

原始问题:unix 时间戳的正确列格式是什么?

网络充满了混乱:一些帖子声称 SQLite 没有无符号类型——不管是什么,或者除了 64 位 int 类型(但有(反)示例调用 UNSIGNED INTEGER)。数据类型页面仅在 bigint 示例中提及它。它还声称有一个 6 字节整数,但没有给出它的名称。似乎我尝试使用 INTEGER 将 4 字节签名的签名存储 unix 时间戳作为负数。我听说有些系统也返回 64 位时间戳。OTOH 我不太喜欢浪费 4 个字节来存储 1 个额外位(时间戳的最高位),即使我必须选择更大的数据格式,我也宁愿选择 6 字节的格式。我什至看过一篇声称 SQLite unix timestamp 是 REAL 类型的帖子......

完整的问题:有人可以澄清一下这个烂摊子吗?

4

5 回答 5

13

SQLite没有无符号类型。这直接来自主要作者以及docs。此外,它没有固定的整数列宽。实际的磁盘宽度是一个实现细节。

SQLite 没有日期或时间数据类型。但是,它具有可以对 ISO8601 字符串 (TEXT)、儒略日数 (REAL) 和 Unix 时间戳 (INTEGER) 进行操作的日期函数。

因此,如果您决定将时间字段设置为 Unix 时间戳,请知道它最多可以存储64位有符号整数,但是您现在存储的值实际上应该占用磁盘上的 32 位,即使源值是 64 位time_t

于 2010-04-07T03:32:47.247 回答
13

整数的大小

SQLite 数据库中的所有列都是内部可变宽度的。文件格式以1、2、3、4、6 或 8 个字节存储整数,具体取决于数字的大小,加上标头中的一个字节来指示大小。因此,在 2038-01-19 之前,以整数形式存储的 Unix 日期总共将占用 5 个字节,之后占用 7 个字节。

从 C API 用户的角度来看,所有整数都是 64 位有符号的。

列类型

是否将列声明为 INTEGER、UNSIGNED INTEGER、BIGINT 或其他类型都没有关系。 任何带有“INT”的东西都具有整数亲和力。 而且,如上所述,所有整数都是有符号的 64 位,但通常不以这种方式存储。

于 2010-04-07T04:47:57.500 回答
0

我的偏好是 64 位整数。无符号 32 位整数的经典情况是自 1970-01-01 到 2038 年用完的秒数。请参阅http://en.wikipedia.org/wiki/Unix_timehttp://en.wikipedia.org/wiki /Year_2038_问题。使用 64 位无符号整数,您是安全的

于 2010-04-06T09:49:00.057 回答
0

您能否举个例子说明“我的尝试似乎是我尝试使用 INTEGER 将 4 字节签名的签名存储 unix 时间戳作为负数。”?

如果您还没有,我建议您阅读有关数据类型(第 1.2 节日期和时间数据类型)和日期和时间函数的 SQLite 文档。

于 2010-04-06T10:04:36.090 回答
0

如果您在内存情况很关键的嵌入式系统上,您可以考虑通过将 64 位值移动几位来降低精度(导致精度为 2、4、8... 秒而不是 1 秒)和使用 32 位值来存储它。

于 2010-04-06T10:14:43.823 回答