2009-02-26 66 views
8

我想計算一個聚合列中所有值的校驗和。創建一個列的聚合校驗和

換句話說,我想要做的

md5(group_concat(some_column)) 

一些等效採用這種方法的問題是:

  1. 這是低效的。在將其傳遞給md5函數之前,它必須將該列的所有值作爲一個字符串連接起來。
  2. group_concat的最大長度爲1024,之後所有其他內容都將被截斷。

(如果你想知道,你能確保值的CONCAT是一致的順序,但是,因爲無論你相信與否GROUP_CONCAT()接受由內這條命令,如group_concat(some_column order by some_column))我提供了非標準的按位集合函數BIT_AND(),BIT_OR()和BIT_XOR(),我認爲這對於這個問題是有用的。在這種情況下,列是數字,但我很想知道是否有方法使用字符串列來完成此操作。

對於這個特定的應用程序,校驗和不必是安全的。

回答

2

好像你還不如用crc32而不是md5如果你不關心加密強度。我認爲這:

select sum(crc32(some_column)) from some_table; 

將工作的字符串。這可能是低效率的,因爲MySQL可能會創建一個臨時表(特別是如果您添加了order by)。

+0

SUM()`在這裏使用是不正確的,因爲兩個不同的校驗和可以很容易地總結到相同的值 – 2013-04-15 19:11:21

1

如果列數字,你可以這樣做:

SELECT BIT_XOR(mycolumn) + SUM(mycolumn) 

當然,這是容易失敗,但它會包括在列中的所有位。

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 
4

以下查詢用於Percona的Mysql Table Checksumming工具。它有點難以理解,但本質上它是針對每一行的列(或一串列連續),然後使用BIT_XOR組函數將它們全部組合在一起。如果一個crc散列值不同,則所有的結果都會不同。這發生在固定的內存中,所以你可以校驗任意大的表。

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

有一點要記住,雖然這並不能阻止可能發生的碰撞,並CRC32是今天的標準相當薄弱的功能。一個更好的散列函數就像FNV_64。當將XOR編輯在一起時,將不太可能具有互補的兩個散列。