Пришлось придумать как сравнить довольно таки объемные таблицы на предмет одинаковости данных в заданном поле.
Сравнивать построчно слишком долго и накладно таскать эти объемы по сети.
Выход посчитать md5 сумму по колонке для всех значений.Для этого выбираем поле по которому будем сравнивать, поле должно быть независимым от серверов.
Делаем из него blob, и считаем md5.Пример: есть таблица A и поле B.
select md5(array_send(array(select B from A order by 1))) as md5;
после это сравнив md5 суммы с обоих серверов можно утверждать об одинаковости набора данных.
URL:
Обсуждается: http://www.opennet.me/tips/info/1994.shtml
Увы, нельзя утверждать. Коллизии никто не отменял.
>Увы, нельзя утверждать. Коллизии никто не отменял.Угу. Только в данном случае вероятностью коллизии можно пренебречь. Потому что вероятность получить один хеш для случайных данных почти нулевая. Другое дело, если подбирать данные целенаправленно.
А если "B" текстовое поле и данных уйма, от такого PostgreSQL ресурсы не съест ?Для текстовых данных лучше еще один вызов md5 добавить:
select md5(array_send(array(select md5(B) from A order by 1))) as md5;
В реальности все намного хуже. Мы же не учитываем порядок и ключ у таблицы. На примере: в первой таблице у Васи 100 рублей, у Пети 200. Во второй - наоборот. Просчет md5 по рублям даст один и тот же результат для этих двух таблиц. Т.е. они типа равны :)Поэтому в реальной ситуации надо использовать ключевые поля. Пусть в таблице A два поля - обычное B и ключевое K, тогда
select md5(array_send(array(select md5('' || K) || md5('' || B) from A order by K))) as md5;
Это, наверное, выйдет за рамки задачи, которая стояла перед автором. :) Хотя довольно интересно. Если развивать Вашу идею далее, может выйти функция, обращающаяся к системным таблицам pg_*. :)
Ну ни кто не запрещал добавлять дополнительные условия во WHERE. Я только предложил методику. Так как у меня порядка 30 миллионов записей в таблице. Мне нужно было сравнить наборы данных. И естественно я просматривал некоторые таблиц разбив на сегменты по дате например.
1. а что мешает делать вывод поля таблицы в файл (используя нужный order by x,y,z), а далее сравнивать по md5 сами файлы?
2. играясь опциями LIMIT/OFFSET можно вычислить "тонкое место" (где данные не совпадают), чтобы не таскать по сети большие объемы. а далее использовать diff...
3. Для этой цели можно написать скриптик, который сам все сделает:
Напр.:
1) с помощью limit/offset выгрузит поле в 100 (1000) файликов.
2) md3sum по ним с рез-тами в файл >> md5_1 (1-й сервер), md5_2 (2-й)
3) diff md5_1 md5_2
4) если найдены расхождения - diff по "несовпадающим" файлам...
Собственно говоря а зачем файлы ?
>Собственно говоря а зачем файлы ?2 причины:
1) меньше нагрузка на БД (?)
2) иногда может потребоваться не только констатировать факт различий, но и найти их...
LIMIT/OFFSET можно использовать на лету. Дальше поиск делением где различия. Нагрузка на БД как раз будет больше при создании файлов. Так как диск используется дважды. + Сортировка по полям съест тотже объем памяти что и при подсчете md5.