9

我想计算汇总列的所有值的校验和。

换句话说,我想做一些等价的

md5(group_concat(some_column))

这种方法的问题是:

  1. 这是低效的。在将列的所有值传递给 md5 函数之前,它必须将列的所有值作为字符串连接到某个临时存储中
  2. group_concat 的最大长度为 1024,之后其他所有内容都将被截断。

(如果您想知道,您可以确保值的连接顺序一致,但是,不管您信不信 group_concat() 接受其中的 order by 子句,例如group_concat(some_column order by some_column)

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

对于这个特定的应用程序,校验和不必是密码安全的。

4

4 回答 4

7

Percona 的 Mysql 表校验和工具中使用了以下查询。它有点难以理解,但本质上它CRC32是每一行的列(或一堆连接的列),然后使用group 函数XOR将它们全部放在一起。BIT_XOR如果一个 crc hash 不同,那么XORing 一切的结果也会不同。这发生在固定内存中,因此您可以对任意大的表进行校验和。

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

需要记住的一件事是,这并不能防止可能的碰撞,而且CRC32按照今天的标准,这是一个相当弱的功能。更好的散列函数类似于FNV_64. XOR当ed 在一起时,不太可能有两个相互补充的哈希。

于 2013-04-15T19:22:53.227 回答
5

如果您不关心加密强度,您似乎也可以使用它crc32md5我认为这:

select sum(crc32(some_column)) from some_table;

将在字符串上工作。它可能效率低下,因为 MySQL 可能会创建一个临时表(特别是如果您添加了order by.

于 2009-02-27T00:12:21.107 回答
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
于 2009-02-26T16:31:04.900 回答
1

如果该列是数字,您可以这样做:

SELECT BIT_XOR(mycolumn) + SUM(mycolumn)

当然这很容易被打败,但它将包括列中的所有位。

于 2009-02-26T16:13:59.807 回答