Il modo migliore per sincronizzare i dati tra due diversi database

19

Devo implementare la sincronizzazione dei dati tra due grandi database che hanno strutture completamente diverse. Fondamentalmente, ho bisogno di inserire alcuni dati sui prodotti in diverse tabelle nel primo database e riordinarli per altre tabelle nel secondo database.

Creare i miei prodotti la prima volta non è molto complicato. Ma sto cercando un modo per aggiornare alcuni dati specifici - non tutti i dati - su ciascun prodotto.

Ovviamente, ci sono alcuni problemi che rendono questo difficile.

  • Non sono autorizzato a fare nulla sul database sorgente a parte le query di selezione.
  • Sul database di destinazione, posso fare query abituali (selezionare, aggiornare, inserire, creare) ma non posso modificare la struttura / le tabelle esistenti.
  • Target e source db hanno strutture completamente diverse, le tabelle non sono affatto le stesse, quindi i dati devono essere riorganizzati - il confronto delle tabelle non funzionerà.
  • Il database di destinazione utilizza un server MySQL - l'origine potrebbe essere DB2.
  • Non ci sono campi "tempo aggiornato" ovunque.

Quindi l'intero processo deve essere eseguito in un singolo script Python (idealmente).

Penso alla creazione di un hash per ogni prodotto, in base ai campi da aggiornare nel database di destinazione: md5 (codice + descrizione + fornitore + circa 10 altri campi). Un nuovo hash basato sugli stessi dati verrà creato su base giornaliera dal database di origine. Conserverò tutti gli hash in una singola tabella (codice articolo, current_hash, old_hash) a scopo di performance. Quindi confronta e aggiorna il prodotto se il nuovo hash è diverso da quello precedente.

Ci sono circa 500 000 prodotti quindi sono un po 'preoccupato per le prestazioni.

È il modo migliore per andare?

    
posta Neow 01.07.2015 - 09:21
fonte

4 risposte

7

Questo è praticamente ciò che ho fatto o vissuto negli ultimi anni, e il mio istinto è che il tempo di leggere 500.000 elementi dal database di origine e la sincronizzazione nella destinazione non ci vorrà più tempo possibile pensa e il tempo impiegato per leggere i campi "chiave", calcolare l'hash MD5 e controllare con la tabella per evitare di sincronizzare gli elementi che non sono cambiati non finirà con il risparmiare troppo tempo e potrebbe anche funzionare più a lungo. Vorrei semplicemente leggere tutto e aggiornare tutto. Se ciò si traduce in un runtime troppo lungo, allora comprimerei il runtime rendendo l'ETL thread-muto, con ogni thread che funziona solo su un segmento della tabella ma che funziona in parallelo.

Sarebbe importante garantire che il database di destinazione abbia un indice chiave principale o un indice univoco. Altrimenti, ciascuno dei tuoi aggiornamenti / inserti potrebbe bloccare l'intera tabella. Ciò sarebbe un problema se si sta adottando l'approccio multithreading, ma è importante anche se si è rimasti single-thread perché il lavoro potrebbe bloccare la tabella DB di destinazione e interferire con l'applicazione che si trova in cima a tale DB.

Si dice che il DB di origine "potrebbe essere DB2". Quando dici "può" implica che DB è ancora progettato / pianificato? DB2 9 o versioni successive ha il monitoraggio integrato dell'ora dell'ultimo aggiornamento e la possibilità di eseguire query e recuperare solo gli elementi modificati da un momento specifico. Forse questo è il motivo per cui il DB è stato progettato per non avere una colonna che indica l'ultima ora aggiornata, ad esempio:

SELECT * FROM T1 WHERE ROW CHANGE TIMESTAMP FOR TAB t1 > current timestamp - 1 hours;

Il limite di timestamp per la query sopra sarebbe l'ultimo timestamp eseguito.

Se questo è il caso, dovrebbe risolvere il tuo problema. Ma la vostra soluzione finirebbe per essere legata strettamente a DB2 e in futuro potrebbero voler passare a un'altra piattaforma DB e aspettarsi che il vostro lavoro di sincronizzazione non debba essere nuovamente visitato. Quindi sarebbe importante assicurarsi che tutte le persone giuste sappiano che il tuo prodotto dipenderà dal rimanere su DB2, o se prevedono di migrare quella migrazione includerebbe la ristrutturazione del DB per avere una colonna "ultimo timestamp modificato" e fare qualunque cosa modifiche necessarie a livello di app per popolare quel campo.

    
risposta data 13.05.2017 - 15:20
fonte
5

La sincronizzazione dei dati sarebbe molto meglio e più veloce, se può essere eseguita sulla base di qualche tipo di identificatore delta o flag. In sostanza, è necessario aggiornare le righe di dati del database di destinazione solo quando non è sincronizzato con il db di origine.

In SQL server db, puoi anche aiutare l' Checksum fn anche a costruire l'identificatore basato sul delta.

Dovresti sviluppare un processo basato su SQL per essere richiamato a una certa ora del giorno o della notte per far scattare questa logica SQL. È preferibile eseguirlo come lavoro SQL notturno, quando l'utilizzo di db è molto basso. Se il delta dei record db di origine e di destinazione non corrisponde, quindi tirare solo quei record. Ma il lato negativo sarebbe quello di calcolare il checksum delle righe di dati di origine ogni volta e quindi confrontarlo con i dati di destinazione.

Se hai una colonna come "LastModifiedDate" nelle tabelle db di origine, puoi saltare l'approccio di checksum. In questo modo, la valutazione verrà eseguita sulla colonna basata sulla data e richiede meno tempo rispetto all'approccio del checksum.

    
risposta data 01.07.2015 - 10:46
fonte
1

Utilizzare l'hash è una buona idea. Poiché la sicurezza non è l'obiettivo in questo caso, scegli una funzione di hash che sia veloce (md5 va bene).

Se non si intende dividere il calcolo dell'hash tra più thread / processi, non è necessario memorizzare il valore hash corrente nel database. Se il tuo processo è un singolo script, avrai solo l'hash corrente in memoria e lo scriverà nel database come hash precedente dopo aver aggiornato i dati nel nuovo database.

    
risposta data 01.07.2015 - 13:29
fonte
-1

dovresti creare un servizio Windows che verrà eseguito ogni volta che lo desideri e che troverà le modifiche nel tuo database di origine e inserirà le modifiche nel tuo database di destinazione.

    
risposta data 13.05.2017 - 12:32
fonte

Leggi altre domande sui tag