2011-09-06 13 views
6

Ho large datasets con milioni di record in formato XML. Questi set di dati sono discariche complete di dati di un database fino a un certo momento.Come posso determinare la differenza tra due grandi set di dati?

Tra due dump potrebbero essere state aggiunte nuove voci e quelle esistenti potrebbero essere state modificate o eliminate. Supponiamo che lo schema rimanga invariato e che ogni voce abbia un ID univoco.

Quale sarebbe il modo migliore per determinare il delta tra due di questi set di dati (incluse eliminazioni e aggiornamenti)?


Il mio piano è caricare tutto su un RDBMS e andare da lì.

Innanzitutto, caricare la discarica precedente. Quindi, caricare il dump più recente in uno schema diverso, ma nel farlo verificherò se la voce è nuova o è un aggiornamento di una voce esistente. Se sì, registrerò l'ID su una nuova tabella (s) chiamata "modifiche".

Al termine, passerò al vecchio dump passando attraverso tutte le voci e vedremo se hanno un record corrispondente (es: stesso ID) sul nuovo dump. In caso contrario, accedere alle modifiche.

Supponendo di cercare un record per ID è un'operazione O(log n), questo dovrebbe consentirmi di fare tutto in tempo O(n log n).

Perché posso determinare la differenza osservando la presenza o l'assenza di record con solo l'ID e l'ultima data di modifica, potrei anche caricare tutto nella memoria principale. La complessità del tempo sarà la stessa, ma con l'ulteriore vantaggio di un minore I/O del disco, che dovrebbe rendere più veloce questo ordine di grandezza.

Suggerimenti? (Nota: questa è più una questione di prestazioni che altro)

+0

"Perché posso determinare ... che dovrebbe rendere questo processo più rapido di ordini di grandezza". "Questa è più una questione di prestazioni che altro". ...così facendo in memoria sarà molto più veloce, e ti preoccuperai principalmente delle prestazioni. Sembra che tu abbia risposto alla tua stessa domanda. – Gerrat

risposta

0

Come suggerimento insolito, considerare l'utilizzo di git per questo. Portare il primo set di dati sotto controllo di versione, quindi pulire la directory di lavoro e copiare nel secondo set di dati. git è dannatamente veloce a far risalire la differenza.

+0

Può gestire questo se i record non sono in ordine particolare (es .: l'ordine non è garantito per rimanere lo stesso)? – NullUserException

+0

@NullUserException: git funziona su strutture di file. Se si sta parlando dell'esportazione di Overflow dello stack, è possibile memorizzare ogni domanda XML in un file questionid.xml (non è sicuro, non ha mai esaminato l'esportazione in dettaglio.) – Andomar

+0

Tutte le domande si trovano nello stesso file XML ... I voglio davvero evitare di creare milioni di file xml ... – NullUserException

0

Dai un'occhiata a questo post su MSDN, che fornisce una soluzione per ottenere le differenze tra due DataTable. Dovrebbe puntare nella giusta direzione:

Come confrontare due DataTable:
http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/23703a85-20c7-4759-806a-fabf4e9f5be6

Si potrebbe anche voler dare un'occhiata a questa domanda SO troppo:
Compare two DataTables to determine rows in one but not the other

ho anche visto questo approccio usato un paio di volte:

table1.Merge(table2); 
DataTable changesTable = table1.GetChanges(); 
0
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

So come farlo, sono più preoccupato per le prestazioni di una query come questa. – NullUserException

+0

@Null Il titolo chiede come determinare la differenza e non come farlo velocemente. Inoltre sembra che tu voglia creare un ciclo e che sarebbe male. –

+0

Come suggerisco di caricare i dati senza un ciclo? – NullUserException

1

Vedere DeltaXML.

(imbottito perché StackOverflow non consente risposte brevi)