Optimale Möglichkeit zum Speichern von Datetime-Werten in der SQLite-Datenbank (Delphi)

8

Ich werde Datetime-Werte in einer SQLite-Datenbank speichern (mit Delphi und der DISqlite-Bibliothek). Die Art der db ist so beschaffen, dass sie niemals zwischen Computern oder Systemen übertragen werden muss, sodass die Interoperabilität keine Einschränkung darstellt. Mein Fokus liegt stattdessen auf der Lesegeschwindigkeit. Das Datum / Uhrzeit-Feld wird indiziert und ich werde viel daran suchen sowie tausende Datetime-Werte nacheinander lesen.

Da SQLite keinen expliziten Datentyp für datetime-Werte besitzt, gibt es mehrere Optionen:

  • verwendet den REAL-Datentyp und speichert die TDateTime-Werte von Delphi direkt: am schnellsten, keine Konvertierung vom String beim Laden; Es ist unmöglich, Daten mit einem Datenbankmanager wie SQLiteSpy zu debuggen, da die Daten nicht lesbar sind. SQLite-Datumsfunktionen (?)

  • können nicht verwendet werden
  • verwenden ein einfaches Zeichenfolgenformat, z. YYYYMMDDHHNNSS: Konvertierung ist erforderlich, aber relativ einfach für die CPU (keine Suche nach Separatoren erforderlich), Daten sind für Menschen lesbar. SQLite-Datumsfunktionen können immer noch nicht verwendet werden.

  • tu etwas anderes. Was ist zu empfehlen?

Ich habe Ссылка gelesen, aber es wird nicht erwähnt, welcher Datentyp verwendet wird, und nicht formal in der Programmierung geschult , Ich konzentriere mich nicht ganz auf julianische Dates. Warum die zusätzliche Konvertierung? Ich werde diese Werte sehr oft lesen, so dass zusätzliche Konvertierungen zwischen Strings und TDateTime einen erheblichen Kostenaufwand bedeuten.

    
Marek Jedliński 21.01.2010, 01:10
quelle

5 Antworten

8

Sie können eines der von SQLite unterstützten String-Formate verwenden, z. %Code%.

Es wäre genauso einfach wie YYYY-MM-DD HH:MM:SS.SSS - Sie müssten immer noch nicht nach Separatoren suchen, da alle Zahlen eine feste Länge haben - und Sie würden SQLite-Datumsfunktionsunterstützung bekommen.

Wenn Sie SQLite-Datumsfunktionsunterstützung benötigen, würde ich mit dieser Methode gehen.

Wenn nicht, würde ich empfehlen, YYYYMMDDHHNNSS -Werte zu verwenden. Sie können sie immer noch miteinander vergleichen (höhere Zahlen sind später) und Datum und Uhrzeit separat betrachten (vor bzw. nach dem Dezimalpunkt), ohne in TDateTime zu konvertieren.

    
Blorgbeard 21.01.2010, 01:28
quelle
5

Ein Kompromiss wäre es, bei REAL-Werten zu bleiben, aber sie als julianische Daten zu speichern, indem Delphi's DateTimeToJulianDate verwendet wird. Auf diese Weise bleiben sie beim Lesen schnell, es gibt nur wenig Leistung in der Konversation, und sie sind immer noch in einem Format, das außerhalb von Delphi sinnvoll ist.

    
Nick Bradbury 21.01.2010 01:48
quelle
2

Dafür benutze ich normalerweise einen Integer-Datentyp und speichere den Unix-Timestamp-Wert (zB # Sekunden seit 1-1-2000). Das Berechnen dieses t / aus einer TDateTime ist gleich dem Multiplizieren / Tauchen mit / durch 86400 und das Hinzufügen einer Konstante für das 'seit'.

Wenn Sie mehr Präzision benötigen Sie könnten die DateTime als FILETIME (zB int64) verwenden, die 100 ns Schritte hat. Dafür gibt es Konvertierungsroutinen in SysUtils und Ihr Zeitstempel wird in UTC gespeichert.

    
Ritsaert Hornstra 21.01.2010 03:43
quelle
0

Wenn Ihr Anliegen nur ein lesbares Format auf Datenbankebene ist, können Sie zwei separate Felder speichern, zum Beispiel:

DELPHI_DATE REAL (DOUBLE, wenn möglich, aber ich kenne SQLite nicht), Indiziert. Alle Ihre programmatischen Abfragen und Vergleiche sollten dieses Feld verwenden.

HUMAN_READABLE_DATE Varchar (23) mit dem Format 'JJJJ-MM-TT HH: MM: SS.SSS'. Vielleicht indiziert (wenn wirklich notwendig). Die Mehrheit der menschlichen Eingabeabfragen sollte dieses Feld enthalten und Sie können (wie von anderen angegeben) SQLite-Datumsfunktionen verwenden.

Es hat einige Nachteile:

  • Der Speicherplatzverbrauch bei Datenbank- und Netzwerkverkehr steigt,
  • Operationen einfügen dauert etwas mehr, weil die Konvertierung notwendig ist,
  • keine automatische Synchronisierung zwischen Werten, wenn sie außerhalb Ihres Programms aktualisiert werden

Wenn es für Ihre speziellen Bedürfnisse geeignet ist, liegt ganz bei Ihnen.

    
jachguate 22.01.2010 02:47
quelle
0

Ich weiß nicht, ob diese Antwort auf die DISqlite-Bibliothek anwendbar ist, aber ...
Im Folgenden finden Sie einen Code, der veranschaulicht, was für mich mit Delphi 2010 und dem SQLite3-Wrapper von Tim Anderson funktioniert.

SQL zum Erstellen eines Felds:

%Vor%

SQL zum Auffüllen des Feldes:

%Vor%

Beispiel für das Abrufen von Daten aus dem Feld:

%Vor%

Ergebnis:

%Vor%

Wie ich in der ersten Zeile erwähnt habe - ich weiß nicht, ob das mit der DISqlite-Bibliothek funktionieren wird, aber ob es eine ziemlich saubere Art der Handhabung von Dingen ist. Ich überlasse es dir, die Dinge hübscher oder eleganter zu machen.

    
TheSteven 10.10.2013 08:34
quelle

Tags und Links