2011-11-30 38 views
11

Actualmente estoy creando manualmente una cadena donde concateno todos los valores en cada fila de mi tabla. Estoy procesando esta cadena para cada fila para obtener un valor hash para los valores actuales (/ estado) de la fila, que luego utilizaré para determinar si la fila ha cambiado.mySQL: obtener valor hash para cada fila?

En lugar de hacerlo manualmente, ¿existe una forma de compilación i mySQL para obtener un valor hash único para cada fila?

Respuesta

17

que podría hacer algo como

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

pero no se puede escapar de la lista los campos que desea, como concat(*) no es una opción (error de sintaxis).

1

Es mejor usar concat_ws(). p.ej. dos columnas adyacentes: 12,3 => 1,23.

Disculpe, esto todavía tiene algunos problemas. Piense en el valor nulo, cadena vacía, cadena puede contener ',', etc ...

Se requiere un programa para generar la instrucción hash, que debe reemplazar nulo por valor específico (para columnas nulables), y también use el char/byte raramente utilizado como separador.

2

Bueno, hice un pequeño script que podría hacer exactamente lo que quieras, y tal vez lo que otros quieren ... así que aquí va ... para PHP que es ... primero tienes que hacer una lista de columnas de la tabla, luego haces una declaración de "caso en caso" para cada columna según su tipo y la pones en la declaración concat_ws y luego la hascas con sha1 ... he usado este método en tablas muy grandes (600000+ registros) y la velocidad es bastante buena cuando se seleccionan todos los registros. También creo que es más rápido a concat los datos requeridos en un CONCAT_WS y explotar en php o lo que sea que esté usando, pero eso es sólo una corazonada ...

<? 
$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

Eso parece una locura –

Cuestiones relacionadas