6 Stimmen

Prüfsumme für eine SQLite-Datenbank?

Ich möchte feststellen können, ob eine SQLite-Datenbankdatei in irgendeiner Weise aktualisiert wurde. Wie würde ich das am besten implementieren?

Die erste Lösung, die mir einfällt, ist der Vergleich von Prüfsummen, aber ich habe keine Erfahrung im Umgang mit Prüfsummen.

7voto

Tino Punkte 8393

Nach Angaben von http://www.sqlite.org/fileformat.html SQLite3 verwaltet eine file change counter in Bytes 24..27 der Datenbankdatei. Sie ist unabhängig von der Datei-Änderungszeit, die sich z. B. nach einer binären Wiederherstellung oder einem Rollback ändern kann, während sich überhaupt nichts geändert hat:

$ sqlite3 test.sqlite 'create table test ( test )'
$ od --skip-bytes 24 --read-bytes=4 -tx1  test.sqlite | sed -n '1s/[^[:space:]]*[[:space:]]//p' | tr -d ' '
00000001
$ sqlite3 test.sqlite "insert into test values ( 'hello world');"
$ od --skip-bytes 24 --read-bytes=4 -tx1  test.sqlite | sed -n '1s/[^[:space:]]*[[:space:]]//p' | tr -d ' '
00000002
$ sqlite3 test.sqlite "delete from test;"
$ od --skip-bytes 24 --read-bytes=4 -tx1  test.sqlite | sed -n '1s/[^[:space:]]*[[:space:]]//p' | tr -d ' '
00000003
$ sqlite3 test.sqlite "begin exclusive; insert into test values (1); rollback;"
$ od --skip-bytes 24 --read-bytes=4 -tx1  test.sqlite | sed -n '1s/[^[:space:]]*[[:space:]]//p' | tr -d ' '
00000003

Um wirklich sicher zu sein, dass zwei Datenbankdateien "gleich" sind, können Sie nur sicher sein, wenn Sie die Dateien dumpen ( .dump ), wodurch die Ausgabe auf den INSERT Anweisungen und sortiert das Ergebnis für den Vergleich (vielleicht durch eine kryptografisch sichere Prüfsumme). Aber das ist schlichtweg Overkill.

2voto

ddevienne Punkte 1698

Eine etwas späte Antwort vielleicht, 10+ Jahre später, aber abgesehen von der Datei-Änderungszähler interessieren sich die Leute vielleicht für die dbhash-Dienstprogramm (aus dem SQLite-Projekt selbst), das eine logisch SHA1-Prüfsumme einer SQLite-Datenbank, die immun ist gegen physisch Unterschiede.

1voto

Dan McGrath Punkte 39478

Je nach Größe der Datenbank kann das ständige Abfragen und Generieren einer Prüfsumme den Rechner überfordern.

Haben Sie in Erwägung gezogen, stattdessen die zuletzt geänderten Metadaten zu überwachen, die im Dateisystem des Betriebssystems gespeichert sind?

1voto

faridz Punkte 679

Wenn eine der Sqlite-Datenbanken nur als Kopie (read only) verwendet wird und Sie überprüfen wollen, ob die ursprüngliche Datenbankdatei aktualisiert wurde, so dass Sie die Kopie aktualisieren können (z.B. aus dem Internet, ohne das Original herunterladen zu müssen, wenn es sich nicht von der Kopie unterscheidet), dann können Sie einfach die ersten 100 Bytes der beiden Datenbankdateien vergleichen (Datenbank-Header) http://www.sqlite.org/fileformat.html

Für die Bytes 24..27 des Datenbank-Headers sagt das SQlite-Dokument:

24..27 4
Der Datei-Änderungszähler. Jedes Mal, wenn eine Datenbanktransaktion übertragen wird, wird der Wert der in diesem Feld gespeicherten 32-Bit-Ganzzahl ohne Vorzeichen inkrementiert

Nach einigen Tests scheint es, dass der Datei-Änderungszähler nicht erhöht wird, wenn eine Datenbanktransaktion übertragen wird, sondern nur Select-Anweisungen enthält, was das gewünschte Verhalten ist, wenn Sie Ihre Selects in eine Transaktion einschließen und übertragen, um die Transaktion zu beenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X