Как я могу определить разницу между двумя большими наборами данных? - PullRequest
6 голосов
/ 06 сентября 2011

У меня большие наборы данных с миллионами записей в формате XML.Эти наборы данных являются полными дампами данных базы данных до определенного момента времени.

Между двумя дампами могут быть добавлены новые записи, а существующие могут быть изменены или удалены.Предположим, что схема остается неизменной, и каждая запись имеет уникальный идентификатор.

Каков наилучший способ определения дельты между двумя из этих наборов данных (включая удаления и обновления)?


Мой план - загрузить все в СУБД и перейти оттуда.

Сначала загрузите старый дамп.Затем загрузите новый дамп в другую схему, но при этом я проверю, является ли запись новой или является обновлением существующей записи.Если да, я зарегистрирую идентификатор в новой таблице (таблицах), называемой «изменения».

После того, как все это будет сделано, я пройду старый дамп, пройдя все записи и посмотрю, есть ли у нихсоответствующая запись (то есть: тот же идентификатор) в новом дампе.Если нет, зарегистрируйтесь для внесения изменений.

Предполагая, что поиск записи по ID является операцией O(log n), это должно позволить мне сделать все за O(n log n) время.

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

Предложения?(Примечание: это больше вопрос производительности, чем что-либо еще)

Ответы [ 5 ]

1 голос
/ 06 сентября 2011

Посмотрите на DeltaXML.

(дополнено, потому что StackOverflow не позволяет короткие ответы)

1 голос
/ 06 сентября 2011
0 голосов
/ 06 сентября 2011
select
    coalesce(a.id, b.id) as id,
    case 
        when a.id is null then 'included' 
        when b.id is null then 'deleted'
        when a.col != b.col then 'updated'
    end as status
from a
full outer join b on a.id = b.id
where a.id is null or b.id is null or a.col != b.col
0 голосов
/ 06 сентября 2011

Взгляните на этот пост в MSDN, который предоставляет решение для получения различий между двумя таблицами данных.Это должно указать вам правильное направление:

Как сравнить два DataTables:http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/23703a85-20c7-4759-806a-fabf4e9f5be6

Возможно, вы также захотите взглянуть на этот вопрос SO: Сравните две таблицы данных, чтобы определить строки в одной, но не в другой

Я также видел, как этот подход использовался несколько раз:

table1.Merge(table2);
DataTable changesTable = table1.GetChanges();
0 голосов
/ 06 сентября 2011

Как необычное предложение, рассмотрите возможность использования git для этого.Переведите первый набор данных под контроль версий, затем очистите рабочий каталог и скопируйте второй набор данных.git чертовски быстро увеличивает разницу.

...