【问题标题】:Creating "checksum" for string in a Firebird/SQLite database在 Firebird/SQLite 数据库中为字符串创建“校验和”
【发布时间】:2020-10-05 17:27:06
【问题描述】:

我需要比较两个不同数据库中声明为字符串的两列,列的所有值,例如一次 10000 行。 一个数据库是 Firebird,一个是 SQLite。我想为两列创建某种校验和,以查看两列中是否存在完全相同的值。

对于整数,我可以创建一个sum(column),如果表格中的总和匹配,我可以假设它具有相同的值。这不是万无一失的,但是如果有很多记录,准确性就会提高。
对于数值,同样可以使用。但是,我不知道如何对字符串列进行类似的操作。

【问题讨论】:

  • 我建议你使用 MD5 或 SHA 之类的哈希,然后比较哈希。使用这种散列,检测错误的可能性非常小。远不如校验和。
  • 一种可能性是获取 Delphi 中的所有字符串值(确保指定 ORDER BY 子句以获得一致的结果)并计算 MD5。您可以为此使用THashMD5。对每个值调用 Update()
  • 一个选项如果您有空间,可以将数据从一个数据库加载到另一个数据库的暂存/临时表中,然后在两个表之间使用 EXCEPT 查询来查看是否有任何行不同。
  • @Brian 如果表 1 包含 AAB 并且表 2 包含 ABB,那么您的 EXCEPT 查询将不会检测任何东西。
  • 关于整数检测的一个侧面说明 - 准确性高度取决于您的数据 - 如果您的整数数据具有相似的值并且在每一行中它可以以相同的增量上下变化 - 给您错误相等的概率不会很低。

标签: sql sqlite delphi firebird


【解决方案1】:

我看到了几种可能性。

1.每行比较

最简单的方法是从 Delphi 代码中逐行检查值。它具有立即发现哪个数据行未同步的巨大好处。

但是如果有从数据库中读取整个数据的缺点。

2。 SQL SELECT 中的哈希

如果您想就地检查,不检索数据,那么您需要计算列的哈希值。

Firebird 4 具有加密哈希函数,如 MD5 或 SHA1,而您 may be able to find a suitable UDF library 则用于较旧的 Firebird 修订版。它们很容易使用 SQLite3 实现,例如 custom aggregate function

确保您对列的 UTF-8 文本版本进行哈希处理,因为二进制/原始存储内容与两个 DB 不兼容。

然后您可以在两个 SELECT SQL 语句中计算列的哈希值。

3.迭代方法

如果数据是插入到数据库中,而不是更新,那么您可以在每一行中添加一个“哈希”字段。当插入一行时,您检索最后一个散列(可能会缓存在内存中以提高效率),然后散列新的附加值。

然后您可以轻松比较最后一行的结果哈希,并检查两个数据库上的数据是否相同。

另一种方法可能是在内存中计算此哈希,而不是作为数据库中的字段。它只会在启动时检索一次数据,然后在插入某些内容时刷新它。检查两个数据库是否同步就足够了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-05
    • 2016-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    • 2015-11-05
    相关资源
    最近更新 更多