校验和SQLite数据库?

时间:2011-01-09 04:56:40

标签: sqlite checksum

我希望能够判断SQLite数据库文件是否已经以任何方式更新。我将如何实施?

我想到的第一个解决方案是比较校验和,但我没有任何使用校验和的经验。

3 个答案:

答案 0 :(得分:6)

根据http://www.sqlite.org/fileformat.html,SQLite3在数据库文件的字节file change counter中维护24..27。它与文件更改时间无关,例如,在二进制恢复或回滚后可以更改而没有任何更改:

$ 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

要确定两个数据库文件“相等”,您只能在转储文件(.dump)之后确定,将输出减少到INSERT语句并对结果进行排序以进行比较(也许通过一些加密安全的校验和)。但这显然有点矫枉过正。

答案 1 :(得分:1)

根据数据库的大小,连续轮询和生成校验和可能对机器来说过于密集。

您是否考虑过监控存储在操作系统文件系统中的最后修改的元数据?

答案 2 :(得分:1)

如果其中一个sqlite数据库仅用作副本(只读),并且您想要检查原始数据库文件是否已更新,以便您可以更新副本(例如,从Web更新,而无需下载如果它与副本没有区别,那么你可以只比较两个数据库文件的前100个字节(数据库头)http://www.sqlite.org/fileformat.html

对于数据库头的字节24..27,SQlite doc说:

  

24..27 4
  文件更改计数器。每次提交数据库事务时,此字段中存储的32位无符号整数的值都会递增

经过一些测试后,似乎在提交数据库事务时文件更改计数器没有递增,但只包含select语句,这是您在事务中包装选择并提交结束事务时所需的行为。