2011-11-30 114 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

这看起来疯狂 –