代码之家  ›  专栏  ›  技术社区  ›  Marek Jedliński

在sqlite数据库(delphi)中存储日期时间值的最佳方法

  •  8
  • Marek Jedliński  · 技术社区  · 15 年前

    我将在sqlite数据库中存储日期时间值(使用delphi和disqlite库)。数据库的性质是,它不需要在计算机或系统之间传输,因此互操作性不是一个约束。我的重点是阅读速度。datetime字段将被索引,我将对其进行大量搜索,并按顺序读取数千个datetime值。

    由于sqlite没有日期时间值的显式数据类型,因此有以下几个选项:

    • 使用真实数据类型并直接存储Delphi的tdateTime值:最快,加载时不转换字符串;无法使用数据库管理器(如sqlitespy)调试日期,因为日期不可读。不能使用sqlite日期函数(?)

    • 使用简单的字符串格式,例如:需要转换,但在CPU上相对容易(不需要扫描分隔符),数据是人可读的。仍然不能使用sqlite日期函数。

    • 做点别的。建议做什么?

    我读过了 http://www.sqlite.org/lang_datefunc.html 但是没有提到要使用什么数据类型,而且,由于没有在编程方面接受过正式的培训,我对朱利安日期没有太多的关注。为什么要进行附加转换?我将大量阅读这些值,因此字符串和tdatetime之间的任何额外转换都会增加很大的成本。

    5 回复  |  直到 11 年前
        1
  •  8
  •   Blorgbeard    15 年前

    您可以使用sqlite支持的字符串格式之一,例如。 YYYY-MM-DD HH:MM:SS.SSS .

    就跟 YYYYMMDDHHNNSS -您仍然不需要扫描分隔符,因为所有的数字都是固定长度的——并且您将获得SQLite日期函数支持。

    如果您需要SQLite日期函数支持,我将使用该方法。

    如果没有,我建议使用 REAL 价值观。您仍然可以将它们相互比较(较大的数字在时间上比较晚),并且可以分别考虑日期和时间(分别在小数点之前和之后),而不必转换为tdatetime。

        2
  •  5
  •   Nick Bradbury    15 年前

    一个折衷办法是坚持实值,但使用Delphi的DateTimeToJuliandate将其存储为朱利安日期。这样,它们就可以保持快速的阅读速度,在对流中几乎没有性能损失,而且它们的格式在Delphi之外仍然是有意义的。

        3
  •  2
  •   Ritsaert Hornstra    15 年前

    为此,我通常使用整数数据类型并以相同的方式存储unix时间戳值(例如,从1-1-2000开始的eq秒)。用tdatetime计算t/等于用86400乘以/下潜,并为“since”添加一个常量。

    如果需要更高的精度,可以将日期时间用作文件时间(如int64),其增量为100 ns。在sysutils中有转换例程,您的时间戳存储在UTC中。

        4
  •  0
  •   jachguate    15 年前

    如果您只关注数据库级别的人类可读格式,则可以存储两个单独的字段,例如:

    德尔菲尔日期 real(如果可能,是double,但我不知道sqlite),索引。所有编程查询和比较都应使用此字段。

    人类可读日期 varchar(23),格式为“yyyy-mm-dd hh:mm:ss.sss”。可能是索引(如果真的需要的话)。大多数人工输入查询应该包括这个字段,您可以使用(如其他人所说)sqlite日期函数。

    它有一些缺点:

    • 数据库空间消耗和网络流量增长,
    • 由于必要的转换,插入操作需要更多的时间,
    • 如果在程序外更新,则值之间没有自动同步

    如果它适合你的特殊需要,就由你决定。

        5
  •  0
  •   TheSteven    11 年前

    我不知道这个答案是否适用于disqlite库,但是…
    下面是一些代码,说明了使用Delphi2010和TimAnderson的sqlite3包装器对我有用的东西。

    要创建字段的SQL:

      sSQL :=  'CREATE TABLE [someTable] (' +
                '  [somefield1] VARCHAR(12),' +
                '  [somefield2] VARCHAR(12),' +
                '  [myDateTime] DATETIME );';
    

    要填充字段的SQL:

     sSQL := 'INSERT INTO someTable(somefield1, somefield2, myDateTime)' + 
             '  VALUES ( "baloney1", "baloney2","' + FloatToStr(Now) + '");';
    

    从字段检索数据的示例:

    var
    sDBFilePathString: string;
    sl3tbl: TSqliteTable;
    fsldb : TSQLiteDatabase;
    FromdbDTField : TDateTime;
    
    begin
       ...
       ... 
        fsldb := TSQLiteDatabase.Create(sDBFilePathString); 
        sl3tbl := fsldb.GetTable('SELECT * FROM someTable');
        FromdbDateTime := StrToFloat(sl3tbl.FieldAsString(sl3tbl.FieldIndex['myDateTime']));
        Showmessage('DT: ' + DateTimeToStr(FromdbDTField));
    end;
    

    结果:

    **DT: 10/10/2013 1:09:53 AM**
    

    正如我在第一行中提到的,我不知道这是否适用于disqlite库,但如果它确实是一种非常干净的处理方式。 我把它留给你是为了使事物更漂亮或更优雅。