创建列的聚合校验和

时间:2009-02-26 16:10:36

标签: sql mysql checksum

我想计算聚合列中所有值的校验和。

换句话说,我想做一些相当于

的事情
md5(group_concat(some_column))

这种方法的问题是:

  1. 效率低下。在将列传递给md5函数之前,它必须将列的所有值作为字符串连接在一些临时存储中
  2. group_concat的最大长度为1024,之后其他所有内容都将被截断。
  3. (如果你想知道,你可以确保值的连续是一致的顺序,但是,不管你信不信,group_concat()接受其中的order by子句,例如group_concat(some_column order by some_column)

    MySQL提供非标准的按位聚合函数BIT_AND(),BIT_OR()和BIT_XOR(),我认为这对这个问题很有用。在这种情况下,该列是数字,但我有兴趣知道是否有办法用字符串列。

    对于此特定应用程序,校验和不必具有加密安全性。

4 个答案:

答案 0 :(得分:5)

以下查询用于Percona的Mysql Table校验和工具。它有点难以理解,但基本上它CRC32是每一行的列(或一堆列连接),然后XOR使用BIT_XOR组函数将它们全部放在一起。如果一个crc哈希值不同,XOR所有内容的结果也会不同。这发生在固定内存中,因此您可以校验任意大的表。

SELECT CONV(BIT_XOR(CAST(CRC32(column) AS UNSIGNED)), 10, 16)

要注意的一点是,这并不能防止可能发生的冲突,CRC32在今天的标准中是一个相当弱的功能。更好的散列函数类似于FNV_64XOR组合在一起时,两个哈希值很可能相互补充。

答案 1 :(得分:3)

SELECT  crc
FROM
(
  SELECT @r := MD5(CONCAT(some_column, @r)) AS crc,
         @c := @c + 1 AS cnt
  FROM
    (
    SELECT @r := '', @c := 0
    ) rc,
    (
    SELECT some_column
    FROM mytable
    WHERE condition = TRUE
    ORDER BY
      other_column
    ) k
) ci
WHERE cnt = @c

答案 2 :(得分:3)

如果您不关心加密强度,似乎您也可以使用crc32而不是md5。我想这个:

select sum(crc32(some_column)) from some_table;

可以处理字符串。它可能是低效的,因为MySQL可能会创建一个临时表(特别是如果你添加了order by)。

答案 3 :(得分:1)

如果列是数字,则可以执行以下操作:

SELECT BIT_XOR(mycolumn) + SUM(mycolumn)

当然这很容易失败,但它会包括列中的所有位。