MySQL: получить хэш-значение для каждой строки?

В настоящее время я вручную создаю строку, в которой я объединяю все значения в каждой строке таблицы. Я использую эту строку для каждой строки, чтобы получить хеш-значение для текущих значений (/status) строки, которые я позже использую, чтобы определить, изменилась ли строка.

Вместо того, чтобы делать это вручную, существует ли встроенный способ я mySQL для получения уникального значения хэша для каждой строки?

Ответ 1

вы можете сделать что-то вроде

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

но вы не можете уйти от перечисления тех полей, которые хотите, поскольку concat(*) не является параметром (синтаксическая ошибка).

Ответ 2

Хорошо, я сделал немного script, который мог бы сделать то, что вы хотите, и, может быть, что другие хотят... так что вот оно... для PHP, который... сначала вы должны составить список столбцов таблицы, затем вы делаете оператор "case when" для каждого столбца на основе их типа и помещаете его в оператор concat_ws, а затем вы используете его с sha1... я использовал этот метод на очень больших таблицах (600000+ записей), и скорость очень хорошая при выборе всех записей. также я думаю, что быстрее конкатцировать требуемые данные в 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";
    ?>

Ответ 3

Лучше использовать concat_ws(). например два соседних столбца: 12,3 = > 1,23.

Извините, это все еще имеет некоторые проблемы. Подумайте о нулевом значении, пустой строке, строка может содержать ',' и т.д.

Для генерации хэш-инструкции требуется программа, которая должна заменять значение null на конкретное значение (для столбцов с нулевым значением), а также использовать редко используемый char/byte в качестве разделителя.