我将日期时间值存储在SQLite数据库中(使用Delphi和DISqlite库)。数据库的性质使得它永远不需要在计算机或系统之间传输,因此互操作性不是约束。我的重点是阅读速度。日期时间字段将被编入索引,我将对其进行大量搜索,并按顺序读取数千个日期时间值。
由于SQLite没有datetime值的显式数据类型,因此有几个选项:
使用REAL数据类型并直接存储Delphi的TDateTime值:最快,加载时不从字符串转换;无法使用数据库管理器(如SQLiteSpy)调试日期,因为日期不会是人类可读的。不能使用SQLite日期函数(?)
使用简单的字符串格式,例如YYYYMMDDHHNNSS:转换是必需的,但在CPU上相对容易(无需扫描分隔符),数据是人类可读的。仍然不能使用SQLite日期函数。
做点别的事。推荐的做法是什么?
我已阅读http://www.sqlite.org/lang_datefunc.html,但没有提及要使用的数据类型,而且,在编程方面没有正式上学,我不太关注朱利安日期。为什么要额外转换?我会仔细阅读这些值,因此字符串和TDateTime之间的任何额外转换都会增加成本。
答案 0 :(得分:8)
您可以使用SQLite支持的字符串格式之一,例如。 YYYY-MM-DD HH:MM:SS.SSS
。
它就像YYYYMMDDHHNNSS
一样简单 - 您仍然不需要扫描分隔符,因为所有数字都是固定长度的 - 您将获得SQLite日期函数支持。
如果您需要SQLite日期功能支持,我会使用该方法。
如果没有,我建议使用REAL
值。您仍然可以将它们相互比较(较高的数字在较晚的时间),并分别考虑日期和时间(分别在小数点之前和之后)而不转换为TDateTime。
答案 1 :(得分:5)
一个折衷方案是坚持使用REAL值,但是使用Delphi的DateTimeToJulianDate将它们存储为julian日期。这样他们仍然可以快速阅读,在对流中几乎没有性能损失,并且它们仍然采用德尔福以外的格式。
答案 2 :(得分:2)
为此,我通常使用Integer数据类型并存储Unix时间戳值(例如,自1-1-2000以来的eq#秒)。从TDateTime计算此t /等于/跳过/跳过86400并为'since'添加一个常量。
如果需要更高的精度您可以将DateTime用作FILETIME(例如int64),其增量为100 ns。 SysUtils中有转换例程,您的时间戳以UTC格式存储。
答案 3 :(得分:0)
如果您的关注点只是数据库级别的人类可读格式,则可以存储两个单独的字段,例如:
DELPHI_DATE REAL(DOUBLE,如果可能,但我不知道SQLite),已编入索引。您的所有程序化查询和比较都应使用此字段。
HUMAN_READABLE_DATE Varchar(23)格式为'YYYY-MM-DD HH:MM:SS.SSS'。也许索引(如果真的有必要)。大多数人工输入查询应包含此字段,您可以使用(如其他人所述)SQLite日期函数。
它有一些缺点:
如果它适合您的特殊需求,由您决定。
答案 4 :(得分:0)
我不知道这个答案是否适用于DISqlite库但是......
下面是一些代码,说明了使用Delphi 2010和Tim Anderson的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库,但是如果它能够以一种非常干净的方式处理事情。 我留给你让它变得更漂亮或更优雅。