The OpenNET Project / Index page

[ новости/++ | форум | wiki | теги | ]

Сравнение таблиц на удаленных серверах PostgreSQL
Пришлось придумать как сравнить довольно таки объемные таблицы на предмет
одинаковости данных в заданном поле.
Сравнивать построчно слишком долго и накладно таскать эти объемы по сети. 
Выход посчитать md5 сумму по колонке для всех значений.

Для этого выбираем поле по которому будем сравнивать, поле должно быть независимым от серверов. 
Делаем из него blob, и считаем md5.

Пример: есть таблица A и поле B.

   select md5(array_send(array(select B from A order by 1))) as md5;

после это сравнив md5 суммы с обоих серверов можно утверждать об одинаковости набора данных.
 
20.03.2009 , Автор: Тормал
Ключи: postgresql, sql, md5, compare / Лицензия: CC-BY
Раздел:    Корень / Программисту и web-разработчику / SQL и базы данных / PostgreSQL специфика / Оптимизация и администрирование PostgreSQL

Обсуждение [ RSS ]
 
  • 1.1, Аноним (1), 14:42, 20/03/2009 [ответить]    [к модератору]
  • +/
    Увы, нельзя утверждать. Коллизии никто не отменял.
     
     
  • 2.2, Aleksey (??), 14:47, 20/03/2009 [^] [ответить]    [к модератору]
  • +/
    >Увы, нельзя утверждать. Коллизии никто не отменял.

    Угу. Только в данном случае вероятностью коллизии можно пренебречь. Потому что вероятность получить один хеш для случайных данных почти нулевая. Другое дело, если подбирать данные целенаправленно.

     
  • 1.3, uldus (ok), 15:11, 20/03/2009 [ответить]    [к модератору]
  • +/
    А если "B" текстовое поле и данных уйма,  от такого PostgreSQL ресурсы не съест ?

    Для текстовых данных лучше еще один вызов md5 добавить:

    select md5(array_send(array(select md5(B) from A order by 1))) as md5;


     
     
  • 2.4, Aleksey (??), 18:29, 20/03/2009 [^] [ответить]    [к модератору]
  • +/
    В реальности все намного хуже. Мы же не учитываем порядок и ключ у таблицы. На примере: в первой таблице у Васи 100 рублей, у Пети 200. Во второй - наоборот. Просчет md5 по рублям даст один и тот же результат для этих двух таблиц. Т.е. они типа равны :)

    Поэтому в реальной ситуации надо использовать ключевые поля. Пусть в таблице A два поля - обычное B и ключевое K, тогда

    select md5(array_send(array(select md5('' || K) || md5('' || B) from A order by K))) as md5;

     
     
  • 3.5, Александр Макаренко (?), 10:41, 22/03/2009 [^] [ответить]    [к модератору]
  • +/
    Это, наверное, выйдет за рамки задачи, которая стояла перед автором. :) Хотя довольно интересно. Если развивать Вашу идею далее, может выйти функция, обращающаяся к системным таблицам pg_*. :)
     
  • 1.6, Тормал (?), 19:07, 23/03/2009 [ответить]    [к модератору]  
  • +/
    Ну ни кто не запрещал добавлять дополнительные условия во WHERE. Я только предложил методику. Так как у меня порядка 30 миллионов записей в таблице. Мне нужно было сравнить  наборы данных. И естественно я просматривал некоторые таблиц разбив на сегменты по дате например.
     
     
  • 2.7, konst (??), 18:15, 24/03/2009 [^] [ответить]    [к модератору]  
  • +/
    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 по "несовпадающим" файлам...

     
     
  • 3.8, Тормал (?), 20:43, 24/03/2009 [^] [ответить]    [к модератору]  
  • +/
    Собственно говоря а зачем файлы ?
     
     
  • 4.9, konst (??), 20:49, 24/03/2009 [^] [ответить]    [к модератору]  
  • +/
    >Собственно говоря а зачем файлы ?

    2 причины:
    1) меньше нагрузка на БД (?)
    2) иногда может потребоваться не только констатировать факт различий, но и найти их...

     
     
  • 5.10, Тормал (?), 20:57, 24/03/2009 [^] [ответить]    [к модератору]  
  • +/
    LIMIT/OFFSET можно использовать на лету. Дальше поиск делением где различия. Нагрузка на БД как раз будет больше при создании файлов. Так как диск используется дважды. + Сортировка по полям съест тотже объем памяти что и при подсчете md5.
     

    Ваш комментарий
    Имя:         
    E-Mail:      
    Заголовок:
    Текст:



      Закладки на сайте
      Проследить за страницей
    Created 1996-2018 by Maxim Chirkov  
    ДобавитьПоддержатьВебмастеруГИД  
    Hosting by Ihor