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

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

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

3 ответов


вы могли бы сделать что-то вроде

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

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


Ну, я сделал небольшой сценарий, который мог бы делать то, что вы хотите, и, возможно, то, что хотят другие... Ну вот и все...для 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";
    ?>

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

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

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