我想计算一个列的所有值的校验和。
换句话说,我想做一些等同于
md5(group_concat(some_column))
这种方法的问题是:
- 效率低下。在将列的所有值传递给 md5 函数之前,它必须将列的所有值作为字符串连接到某个临时存储中
- group_concat 的最大长度为 1024,之后的所有内容都将被截断。
(如果您想知道,您可以确保值的连接顺序一致,但是,无论您相信与否,group_concat() 都接受其中的 order by 子句,例如 group_concat( some_column order by some_column)
)
MySQL 提供了非标准的按位聚合函数 BIT_AND()、BIT_OR() 和 BIT_XOR(),我认为它们对解决这个问题很有用。在这种情况下,该列是数字的,但我很想知道是否有办法用字符串列来做到这一点。
对于这个特定的应用程序,校验和不必是密码安全的。
最佳答案
以下查询用于 Percona 的 Mysql 表校验和工具。它有点难以理解,但本质上它是用 CRC32
对每一行的列(或一组连续的列)进行 XOR
使用 将它们全部放在一起>BIT_XOR
组函数。如果一个 crc hash 不同,则 XOR
的结果也会不同。这发生在固定内存中,因此您可以对任意大的表进行校验和。
SELECT CONV(BIT_XOR(CAST(CRC32(column) AS UNSIGNED)), 10, 16)
尽管这不能防止可能的冲突,但要记住一件事,而且 CRC32
按照今天的标准是一个非常弱的函数。更好的散列函数类似于 FNV_64
。当异或
在一起时,不太可能有两个相互补充的散列。
关于sql - 创建列的聚合校验和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/591234/