Alternative per confrontare dati da diversi database

5

Ho due enormi tabelle su database separati. Uno di questi ha l'informazione di tutti gli SMS che sono passati attraverso i server dell'azienda mentre l'altro ha le informazioni sulla fatturazione effettiva di quegli SMS.

Il mio lavoro consiste nel confrontare campioni di entrambe queste tabelle (ad esempio, i record tra 1 e 2 pm) per vedere se ci sono delle differenze: SMS che sono stati inviati ma non addebitati all'utente per qualunque motivo possa essere accadendo.

Le colonne che utilizzerò per confrontare sono il numero di telefono del destinatario e la data esatta in cui è stato inviato l'SMS. Un problema qui è che le date di solito sono le stesse su entrambi i lati, ma in molti casi differiscono di 1 o 2 secondi.

Ho, finora, due alternative per fare questo:

  1. (PL / SQL) Crea due tabelle in cui conserverò temporaneamente tutti i record di quell'esempio di 1 ora. Uno per ciascuno dei tavoli principali. Quindi, per ciascun numero di telefono distinto, selezionare l'ora di ogni SMS inviato da quel telefono da entrambe le mie tabelle temporanee e avviare il confronto uno per uno utilizzando i cursori. In questo caso, la procedura verrebbe eseguita sul server in cui una delle sorgenti è così il contenuto dell'altro verrà cercato usando un dblink.

  2. (sqlplus + c ++) Invece di memorizzare i campioni 1 ora in nuove tabelle, invia la query a un file di testo. Avrò due file di testo, uno per ogni fonte. Quindi, apri il primo file e carica tutto il suo contenuto su un hash_map (valore-chiave) usando c ++, dove la chiave sarà il numero di telefono e il valore un elenco di volte di SMS inviati da quel telefono. Infine, apri il secondo file, prendi ogni riga (in questo formato: numberX timeX), cerca la voce di numberX su hash_map (che sarà un elenco di volte) e poi controlla se timeX è in quella lista. Se non lo è, salvalo da qualche parte per archiviarlo infine su una tabella "scaricata" (questo sarebbe anche il passaggio finale del caso 1)

La mia preoccupazione principale è l'efficienza. Questi campioni hanno circa 2 milioni di record su ciascuna fonte, quindi non è possibile afferrare un record da un lato e cercare l'altro dall'altro. Questa è la ragione per cui volevo usare hash_maps

Quale pensi sia un'opzione migliore?

    
posta Alex 01.06.2012 - 20:12
fonte

5 risposte

1

Se i database si trovano sullo stesso server, puoi semplicemente eseguire una query contro entrambi database .

In caso contrario, potresti utilizzare Gateway del database Oracle (se ce l'hai) per connetterti ad entrambi, e allo stesso modo fanno il confronto.

    
risposta data 01.06.2012 - 20:31
fonte
1

A prima vista, la tua seconda opzione sarà probabilmente superiore.
Ecco la mia linea di pensiero e ipotesi.

0) Suppongo che tu non abbia un sistema di database enorme seduto in attesa di una query come questa per giustificare il suo scopo.

1) Probabilmente avrai eseguito più volte. Se non altro, una volta risolte le discrepanze nell'elaborazione delle fatture, questo processo di verifica sarà necessario per convalidare le correzioni.

2) Le operazioni parallele saranno fondamentali per ottenere tempi di esecuzione ragionevoli. La seconda opzione che suggerisci ti permetterà di suddividere le cose in blocchi di singoli elenchi "inviati" e mappature "fatturate". Questi blocchi possono essere distribuiti ai client distribuiti per tempi di elaborazione più rapidi.

3) Il codice C ++ offre più opzioni per gestire le discrepanze temporali e la successiva (ri) elaborazione di tali voci.

    
risposta data 01.06.2012 - 23:16
fonte
1

Ecco un modo molto efficace per confrontare due query (soluzione generalizzata per il problema di confrontare due tabelle in modo efficiente):

SELECT * FROM
(
  SELECT foo1 col1, foo2 col2 FROM ...
  UNION ALL
  SELECT bar1 col1, bar2 col2 FROM ...
) t
GROUP BY col1, col2
HAVING COUNT(*) = 1

Questa query prende due sottoquery che dovrebbero essere identiche e l'output è le righe che si trovano solo in una delle query. In altre parole, se le due sottoquery restituiscono righe identiche, l'output dovrebbe essere vuoto.

Avevo bisogno di confrontare due insiemi di dati di grandi dimensioni in passato, in cui la prestazione era una preoccupazione importante, e questo era di gran lunga il metodo più veloce che ho trovato.

Hai detto che i timestamp possono avere qualche secondo di differenza. Per nascondere quel rumore, ti consiglio di utilizzare un tipo di arrotondamento della data, ma non conosco la sintassi per questo.

    
risposta data 01.06.2012 - 22:09
fonte
0

Due milioni di record non dovrebbero essere un grosso problema, specialmente se il numero di telefono è indicizzato. Quindi il tuo tempo è probabilmente più importante del tempo di interrogazione. Diamine, probabilmente creerei una tabella e importerei tutti i record da un database all'altro se non potessi fare altrimenti riferimento ad entrambi in una query.

Quindi, presumo che tu possa fare riferimento a entrambe le tabelle in una query.

La logica per la corrispondenza all'interno della finestra 2 secondi è alquanto complicata. Ad esempio, cosa succede se c'era un SMS alle 12:00:01 e alle 12:00:05 e un conto alle 12:00:03? Davvero, uno dei due non è stato addebitato.

Quindi quello che vuoi veramente come primo passo è quello di abbinare il conteggio dei messaggi SMS e il numero di messaggi fatturati per un numero di telefono. In seguito puoi capire quale non è stato fatturato (o forse non hai abbastanza informazioni per farlo in modo preciso, come nel mio esempio).

Possiamo farlo:

SELECT A.PhoneNumber,SentCount,BilledCount 
FROM 
     (SELECT SentMessages.PhoneNumber, Count(SentMessages.SentDate) as SentCount
        FROM SentMessage
    GROUP BY SentMessages.PhoneNumber) as A JOIN
      (SELECT BilledMessages.PhoneNumber, Count(BilledMessages.BilledDate) as BilledCount
        FROM BilledMessages
    GROUP BY BilledMessages.PhoneNumber) AS B
          ON A.PhoneNumber=B.PhoneNumber
       WHERE SentCount>BilledCount

E potremmo anche eseguire tutto ciò sull'intero tavolo come esempio - eccetto che forse alcuni messaggi non dovrebbero essere stati ancora fatturati, quindi non vogliamo quelli. Questo è al di fuori della portata della domanda comunque.

    
risposta data 01.06.2012 - 23:15
fonte
0

Suggerisco di creare un link al database tra i due database, ti consente di accedere a una tabella remota come se fosse nello stesso database.

Una volta ottenuto il collegamento al database, codifica la soluzione in una procedura PL / SQL del negozio

.

Suggerisco PL / SQL Developer come IDE per la procedura di scrittura del negozio.

    
risposta data 24.08.2012 - 22:36
fonte

Leggi altre domande sui tag