2011-09-06 22 views
6

Tengo large datasets con millones de registros en formato XML. Estos conjuntos de datos son volcados completos de datos de una base de datos hasta cierto punto en el tiempo.¿Cómo puedo determinar la diferencia entre dos grandes conjuntos de datos?

Entre dos volcados se pueden haber agregado nuevas entradas y las existentes pueden haberse modificado o eliminado. Supongamos que el esquema permanece sin cambios y que cada entrada tiene una ID única.

¿Cuál sería la mejor manera de determinar el delta entre dos de estos conjuntos de datos (incluidas las eliminaciones y actualizaciones)?


Mi plan es cargar todo en un RDBMS e ir desde allí.

Primero, cargue el volcado anterior. Luego, cargue el volcado más nuevo en un esquema diferente, pero al hacerlo verificará si la entrada es nueva o es una actualización de una entrada existente. En caso afirmativo, registraré la identificación en una nueva tabla llamada "cambios".

Una vez hecho esto, iré a través del antiguo volcado revisando todas las entradas y veré si tienen un registro coincidente (es decir, la misma ID) en el nuevo volcado. De lo contrario, inicie sesión en los cambios.

Suponiendo que buscar un registro por ID es una operación O(log n), esto debería permitirme hacer todo en O(n log n) vez.

Como puedo determinar la diferencia observando la presencia o la ausencia de registros con solo la ID y la última fecha de modificación, también pude cargar todo en la memoria principal. La complejidad del tiempo será la misma, pero con el beneficio adicional de menos E/S de disco, lo que debería hacer que esto sea más rápido en órdenes de magnitud.

Sugerencias? (Nota: esta es más una pregunta de rendimiento que cualquier otra cosa)

+0

"Porque puedo determinar ... lo que debería hacer esto más rápido en órdenes de magnitud". "Esta es más una cuestión de rendimiento que cualquier otra cosa". ...Así que hacer esto en la memoria será mucho más rápido y lo que más le preocupa es el rendimiento. Parece que respondiste tu propia pregunta. – Gerrat

Respuesta

0

Como sugerencia inusual, considere usar git para esto. Ponga el primer conjunto de datos bajo control de versión, luego limpie su directorio de trabajo y copie en el segundo conjunto de datos. git es extremadamente rápido al mencionar la diferencia.

+0

¿Puede manejar eso si los registros no están en un orden particular (es decir: no se garantiza que la orden se mantenga igual)? – NullUserException

+0

@NullUserException: git funciona en estructuras de archivos. Si está hablando de la exportación de Stack Overflow, puede almacenar cada pregunta XML en un archivo questionid.xml (no estoy seguro, nunca miré la exportación en detalle). – Andomar

+0

Todas las preguntas están en el mismo archivo XML ... I realmente quiero evitar la creación de millones de archivos xml ... – NullUserException

0

Eche un vistazo a esta publicación en MSDN, que proporciona una solución para obtener las diferencias entre dos DataTables. Se debe apuntar en la dirección correcta:

Cómo comparar dos tablas de datos:
http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/23703a85-20c7-4759-806a-fabf4e9f5be6

También puede ser que desee echar un vistazo a esta cuestión de forma demasiado:
Compare two DataTables to determine rows in one but not the other

tengo también ve este enfoque utiliza un par de veces:

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

Sé cómo hacerlo, estoy más preocupado por el rendimiento de una consulta como esta. – NullUserException

+0

@Null El título pregunta cómo determinar la diferencia, no cómo hacerlo rápido. También parece que quieres crear un bucle y eso sería malo. –

+0

¿Cómo sugieres que cargue los datos sin un bucle? – NullUserException

1

Mira DeltaXML.

(acolchada porque stackoverflow no permite respuestas cortas)

Cuestiones relacionadas