Tengo que implementar la sincronización de datos entre dos grandes bases de datos que tienen estructuras completamente diferentes. Básicamente, necesito recopilar algunos datos sobre productos en diferentes tablas en la primera base de datos y reorganizarlos para otras tablas en la segunda base de datos.
Crear mis productos por primera vez no es muy complicado. Pero estoy buscando una manera de actualizar algunos datos específicos, no todos, sobre cada producto.
Obviamente, hay algunos problemas que hacen que esto sea complicado.
- No se me permite hacer nada en la base de datos de origen, aparte de las consultas de selección.
- En la base de datos de destino, puedo hacer consultas habituales (seleccionar, actualizar, insertar, crear) pero no puedo modificar la estructura / tablas existentes.
- La base de datos de destino y fuente tienen estructuras completamente diferentes, las tablas no son iguales, por lo tanto, los datos realmente tienen que reorganizarse: la comparación de tablas no funcionará.
- La base de datos de destino utiliza un servidor MySQL; la fuente puede ser DB2.
- No hay campos de "hora actualizada" en ninguna parte.
Por lo tanto, todo el proceso debe hacerse en un solo script de Python (idealmente).
Pienso en crear un hash para cada producto, basado en los campos para actualizar en la base de datos de destino: md5 (código + descripción + proveedor + alrededor de otros 10 campos). A partir de la base de datos de origen se creará diariamente un nuevo hash basado en los mismos datos. Almacenaré todos los hashes en una sola tabla (código de artículo, current_hash, old_hash) para fines de rendimiento. Luego compare y actualice el producto si el nuevo hash es diferente del anterior.
Hay alrededor de 500 000 productos, así que estoy un poco preocupado por las actuaciones.
¿Es el buen camino a seguir?
Respuestas:
Esto es más o menos lo que he estado haciendo o viviendo en los últimos años, y mi instinto es que el tiempo para leer 500,000 artículos de la base de datos de origen y la sincronización en el destino no tomará tanto tiempo como uno podría pensar y el el tiempo necesario para leer los campos "clave", calcular el hash MD5 y realizar una verificación cruzada con su tabla para evitar la sincronización de elementos que no han cambiado no terminará ahorrando demasiado tiempo e incluso puede durar más. Simplemente lo leería todo y lo actualizaría todo. Si eso resulta en un tiempo de ejecución que es demasiado largo, entonces comprimiría el tiempo de ejecución haciendo que el ETL sea multiproceso, con cada subproceso operando solo en un segmento de la tabla pero trabajando en paralelo.
Sería importante asegurarse de que su base de datos de destino tenga un índice de clave principal o un índice único. De lo contrario, cada una de sus actualizaciones / inserciones podría bloquear toda la tabla. Esto sería malo si está adoptando el enfoque de subprocesos múltiples, pero importante incluso si permanece con un solo subproceso porque su trabajo podría bloquear la tabla de base de datos de destino e interferir con la aplicación que se encuentra encima de esa base de datos.
Usted dice que la base de datos "puede ser DB2". Cuando dice "puede", ¿implica que DB todavía se está diseñando / planificando? DB2 9 o superior tiene un seguimiento incorporado del último tiempo de actualización y la capacidad de consultar y recuperar solo los elementos que han cambiado desde un momento determinado. Quizás es por eso que el DB fue diseñado para no tener una columna que indique la última hora actualizada, por ejemplo:
El límite de la marca de tiempo para la consulta anterior sería la última marca de tiempo que ejecutó su sincronización.
Si este es el caso, eso debería resolver su problema. Sin embargo, su solución terminaría estando estrechamente vinculada a DB2 y, en el futuro, les gustaría pasar a otra plataforma de base de datos y esperar que su trabajo de sincronización no necesite ser revisado nuevamente. Por lo tanto, sería importante asegurarse de que todas las personas adecuadas sepan que su producto dependerá de permanecer en DB2, o si planean migrar esa migración incluiría la reestructuración de la base de datos para que tenga una columna de "último cambio de fecha y hora", y hacer lo que sea cambios necesarios en el nivel de la aplicación para llenar ese campo.
fuente
La sincronización de datos sería mucho mejor y más rápida, si se puede hacer sobre la base de algún tipo de identificador o indicador delta. Básicamente, debe actualizar las filas de datos de db de destino solo cuando no esté sincronizado con el db de origen.
En SQL Server DB, puede tomar la ayuda de Checksum fn también para construir el identificador basado en delta.
Debería desarrollar un trabajo basado en SQL para ser invocado a una determinada hora del día o de la noche para activar esta lógica SQL. Es mejor ejecutarlo como un trabajo nocturno de SQL, cuando el uso de db es muy bajo. Si el delta del origen y los registros db de destino no coinciden, solo extraiga esos registros. Pero la desventaja sería calcular la suma de verificación de las filas de datos de origen cada vez y luego compararla con los datos de destino.
Si tiene una columna como "LastModifiedDate" en las tablas de base de datos de origen, puede omitir el enfoque de suma de comprobación. De esta forma, su evaluación se ejecutará en la columna basada en la fecha y tomará menos tiempo en comparación con el enfoque de suma de verificación.
fuente
Usar un hash es una buena idea. Dado que la seguridad no es el objetivo en este caso, elija una función hash que sea rápida (md5 está bien).
A menos que planee dividir el cálculo de hash en múltiples subprocesos / procesos, realmente no necesita almacenar el valor de hash actual en la base de datos. Si su proceso es un solo script, solo tendrá el hash actual en la memoria y lo escribirá en la base de datos como el hash anterior después de haber actualizado los datos en la nueva base de datos.
fuente
debería haber creado un servicio de Windows que se ejecutará en algunos momentos específicos cuando lo desee y encontrará los cambios en su base de datos de origen e insertará esos cambios en su base de datos de destino.
fuente