2011-11-30 115 views
11

目前我手動創建一個字符串,我連接我的表中的每一行中的所有值。我爲每行對這個字符串進行哈希處理,以獲得該行當前值(/狀態)的哈希值,我稍後使用它來確定該行是否已更改。mySQL:獲取每一行的散列值?

而不是手動這樣做,是否有內置的方式我mySQL獲得每行獨特的哈希值?

回答

17

你可以做類似

SELECT MD5(concat(field1, field2, field3, ...)) AS rowhash 

,但你不能從上市的字段你想要的,因爲concat(*)不是一個選項(語法錯誤)的距離。

1

最好使用concat_ws()。例如兩個相鄰的列:12,3 => 1,23。

對不起,這仍然有一些問題。考慮空值,空字符串,字符串可以包含','等等......

需要一個程序來生成哈希語句,它應該將null替換爲特定的值(對於無空列),並且也使用很少使用的字符/字節作爲分隔符。

2

那麼我做了一個小腳本,可以做很多你想要的東西,也許別人想要的......所以在這裏...對於PHP ... 首先,你必須列出列的表,然後你根據它們的類型爲每一列創建一個「case when」語句,並將其放在concat_ws語句中,然後用sha1對它進行哈希處理...我在非常大的表上使用了這種方法(600000+記錄),選擇所有記錄時速度非常好。我也覺得這是更快Concat的一個CONCAT_WS所需的數據和在PHP或任何你正在使用爆炸,但是這只是一種預感......

<? 
$query= mysql_query("SHOW COLUMNS FROM $table", $linklive); 
     while ($col = mysql_fetch_assoc($query)) { 
      $columns[] = mysql_real_escape_string($col['Field']); 
      if ($col['Key'] == 'PRI') { 
       $key = mysql_real_escape_string($col['Field']); 
      } 
      $columnsinfo[$col['Field']] = $col; 
     } 
     $dates = array("date","datetime","time"); 
        $int = array("int","decimal"); 
        $implcols = array(); 
        foreach($columns as $col){ 
         if(in_array($columnsinfo[$col]['Type'], $dates)){ 
          $implcols[] = "(CASE WHEN (UNIX_TIMESTAMP(`$col`)=0 || `$col` IS NULL) THEN '[$col EMPTY]' ELSE `$col` END)"; 
         }else{ 
          list($type, $rest) = explode("(",$columnsinfo[$col]['Type']); 
          if(in_array($columnsinfo[$col]['Type'], $dates)){ 
           $implcols[] = "(CASE WHEN (`$col`=0 || `$col` IS NULL) THEN '[$col EMPTY]' ELSE `$col` END)"; 
          }else{ 
           $implcols[] = "(CASE WHEN (`$col`='' || `$col` IS NULL) THEN '[$col EMPTY]' ELSE `$col` END)"; 
          } 
         } 
        } 
        $keyslive = array(); 
        //echo "SELECT $key SHA1(CONCAT_WS('',".implode(",", $columns).")) as compare FROM $table"; exit; 
        $q = "SELECT $key as `key`, SHA1(CONCAT_WS('',".implode(", ",$implcols).")) as compare FROM $table"; 
    ?> 
+8

這看起來瘋狂 –