如何在SQLite中存储日期时间

时间:2014-11-17 17:27:14

标签: android sqlite datetime android-sqlite database-performance

这与被关闭的another question非常相似,不是真正的问题。我试图对它进行编辑以使其有效重新开放,但被告知我最好再问一个新问题。

我正在开发android,需要在sqlite数据库中存储datetime值,以跟踪将生成通知的重复事件。我还需要能够根据时间范围查询数据库。

SQLite documentation表示它不支持特定日期类型,但可以使用TEXT,REAL或INTEGER类型表示日期:

  

TEXT as ISO8601字符串(“YYYY-MM-DD HH:MM:SS.SSS”)。

     

真实的朱利安日数,即公元前4714年11月24日格林威治中午以来的天数。根据公历格里高利历。

     

INTEGER as Unix Time,自1970-01-01 00:00:00 UTC以来的秒数。

最初的好处似乎是:

  • TEXT对数据库中的可读性非常有用,能够在以后直接显示(无需转换),但如果需要对它们进行计算则成本很高。从时区引入可能的错误。
  • 真正适用于1970年以前的日期,适合计算或日期比较。不代表时间,只代表几天。
  • INTEGER可用于计算或日期时间比较,非常好的兼容性,因为它是一个广泛支持的标准。

这听起来不错吗?使用INTEGER作为日期时间会使查询时间范围明显快于使用TEXT时的速度吗?还有其他我没有考虑过的事情吗?

根据我的用例,哪些解决方案最好?

4 个答案:

答案 0 :(得分:4)

  

TEXT对数据库中的可读性非常有用,可以在以后直接显示(无需转换)

ISO格式通常不用于显示;你也必须改变它。 (此格式对于调试更有用。)

  如果需要对它们进行计算,则成本很高

对于数据库,瓶颈通常是I / O. 我怀疑你会看到一个查询,其中日期值的实际格式会产生明显的差异。

  

从时区引入可能的错误。

TEXT格式没有时区说明符,但没有其他格式。 如果您说所有数据库值都是UTC,则没有区别。

  

真正适用于1970年以前的日期

所有格式都支持0到9999之间的所有年份。(整数可以是负数。)

  

不代表时间,仅代表数天。

时间表示为小数值。

  

INTEGER ...非常好的兼容性,因为它是一个广泛支持的标准。

但Java使用的是毫秒,而不是秒。

  

还有其他我未考虑过的事情吗?

大多数built-in date functions的默认输出格式是TEXT。


  

根据我的用例,哪些解决方案最好?

我会说TEXT,但我认为不会有太大差异。

答案 1 :(得分:1)

这里的答案主要是意见,但如果我是你,我会使用INTEGER类型并存储unix时间戳。它似乎不太依赖于格式转换/解析,而且是最普遍支持的标准。

答案 2 :(得分:0)

  

不代表时间,仅代表数天。

这就是REAL的小数部分。

  

使用INTEGER作为日期时间会使查询时间范围明显快于使用TEXT时的速度吗?

最有可能。我无法想象一种情况,其中字符串比较比整数比较更快,特别是对于查询中的索引列。

  

还有其他我未考虑过的事情吗?

我不知道你是否考虑过the effects of gamma rays on man-in-the-moon marigolds,但这并不重要。 : - )

  

根据我的用例,哪些解决方案最好?

INTEGER,恕我直言。

答案 3 :(得分:0)

将UTC日期时间存储为SQLite中的8字节64位整数。 Millis sence 1970。

long time= System.currentTimeMillis();

使用索引数据库,您可以在日期读取数据之间和之间对大约10k行进行出色的响应。

将时区操作留给视图层,因为具有所有UTC时间的数据库将在全球范围内工作。

不要将日期存储为如此古老且在现代应用程序中没有位置的文本。

我会避免仅存储日期,因为现代应用会在事件发生时考虑到。您可以使用8个字节存储日期时间。但是,如果你必须,你可以简单地将iso日期放入1999-12-31的整数作为19991231,并以sqllite存储一个4字节的整数。