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 в качестве разделителя.