2010-09-17 27 views
6

Sto scrivendo del codice per trovare i dettagli del cliente duplicati in un database. Userò la distanza di Levenshtein.Come memorizzare i rapporti bidirezionali

Tuttavia, non sono sicuro di come memorizzare le relazioni. Uso sempre le basi di dati ma non ho mai incontrato questa situazione e mi sono chiesto se qualcuno potesse indicarmi la giusta direzione.

Ciò che mi confonde è come memorizzare la natura bidirezionale della relazione.

ho iniziato a mettere alcuni esempi che seguono, ma si chiede se c'è una buona pratica per la memorizzazione di questo tipo di dati,

dati Esempio

id, indirizzi

001, 5 Main Street
002, 5 Main St.
003, 5 Main Str
004, 6 High Street
005, 7 Low Street
006, 7 Basso St

Suggerimento 1

customer_id1, customer_id2, relationship_strength
001, 002, 0,74
001, 003, 0,77
002, 003, 0,76
005, 006, 0,77

Non contento di questo approccio come una sorta di deduce una relazione a senso unico tra Cust omer_id1 a customer_id2. A meno che non includa tutte le relazioni in entrambi i modi, ma ciò raddoppierà la quantità di tempo di elaborazione e la dimensione delle tabelle.

esempio dovrebbe includere: 002, 001, 0,74

suggerimento 2

customer_id, GROUPING_ID
001, 1
002, 1
003, 1
005, 2
006, 2

risposta

6

Quello che abbiamo qui è un grafico in cui ogni nodo ha una relazione (modifica distanza) con ogni altro nodo. Questo non è nella normale gamma di modelli di dati. Inoltre, non è una caratteristica permanente del tuo database (supponendo che tu risolva i processi aziendali che hanno portato ai dati duplicati), quindi non vale la pena di sudare sulla soluzione che meglio si adatta alla teoria relazionale. Ciò di cui abbiamo bisogno è una soluzione pratica.

Pensatelo come una matrice. Se procediamo all'elaborazione ottimale, non eseguiremo i punteggi duplicati. Quindi assegniamo l'indirizzo 1 a tutti gli altri indirizzi, classifichiamo l'indirizzo 2 contro tutti gli altri indirizzi eccetto l'indirizzo 1, classifichiamo l'indirizzo 3 contro tutti gli altri indirizzi eccetto gli indirizzi 1 e 2, ecc. E quello che finiamo è un po ' come una graduatoria di calcio:

  addr 
      1 2  3 4  5 
addr 
    1  - 95 95 80 76 
    2  - - 100 75 72 
    3  - -  - 75 72 
    4  - -  - - 83 
    5  - -  - -  - 

Questi dati possono essere immagazzinate nella migliore suggerimento 1, una tabella di ID1, ID2, SCORE. Anche se abbiamo bisogno di ruotare i dati per ottenere l'output simile :)

In una tabella di campionato corretta ci sono due serie di punteggi - Casa e Fuori - quindi il tavolo è simmetrico. Ma ciò non si applica qui, poiché la distanza di modifica per 1 > 2 corrisponde a 2 > 1. Tuttavia, renderebbe l'interrogazione dei risultati più semplice se il set di risultati includesse i punteggi speculari. Cioè, per i record (1,5,76), (2,5,72), ecc., Generiamo i record (5,1,76), (5,2,72). Questo potrebbe essere fatto alla fine del processo di punteggio.

  addr 
      1 2  3 4  5 
addr 
    1  - 95 95 80 76 
    2  95 - 100 75 72 
    3  95 100  - 75 72 
    4  80 75 75 - 83 
    5  76 72 72 83  - 

Naturalmente, questo è principalmente una cosa di presentazione, quindi ha bisogno solo di essere fatto per scopi di visualizzazione, per esempio esportando i dati in un foglio di calcolo. Possiamo ancora ottenere tutti i punteggi per, diciamo, Indirizzo 5 in modo leggibile senza miiroring i punteggi utilizzando una semplice istruzione SQL:

select case when id1 = 5 then id1 else id2 end as id1 
     , case when id1 = 5 then id2 else id1 end as id2 
     , score 
from your_table 
where id1 = 5 
or  id2 = 5 
/
+0

Grazie APC. Quella matrice ha senso e aiuta a visualizzarla. Quella dichiarazione SQL è davvero anche a mano. Grazie. – alj

1

Come sempre dipende da cosa vuoi fare con i dati una volta calcolato.

Supponendo che sia semplicemente per identificare o individuare i duplicati, il tuo suggerimento 1 è quello che userei, cioè una seconda tabella che semplicemente memorizza le coppie e i punti di forza. Il mio unico suggerimento è di rendere i punti di forza un numero intero in scala piuttosto che un decimale.

+0

Ho bisogno di presentare i dati alle persone che li mantengono in modo che possano passare e controllarli. Quindi, a tale riguardo, il mio primo suggerimento sarebbe sufficiente, suppongo. Ma volevo sapere se esistesse un modo "standard" di archiviare tali informazioni in modo da avere la flessibilità di produrlo in vari formati a seconda di cosa volessero (poiché senza dubbio torneranno dicendo che vogliono farlo in un altro modo!). Inoltre ... è una buona opportunità per migliorare la mia comprensione dello schema del database. – alj

+0

... e grazie Richard. – alj

+0

È il modo in cui l'ho sempre fatto. A volte la soluzione più semplice funziona e non è necessario cercare qualcosa di più complesso. La prima soluzione funzionerà e sarà sufficientemente efficiente e produrrà i risultati necessari. –

6

Il modo per affrontare le relazioni simmetriche in un sistema relazionale è la seguente:

  • scegliere una forma canonica in cui sono memorizzate le coppie simmetriche, ad es. customer_id1 < customer_id2.
  • definire una vista SYMM_TBL come selezionare ID1, ID2, ... da ... UNION SELECT id2 come ID1, ID1 come ID2, ... FROM ...

sistemi decenti non si dovrebbe punire in l'area delle prestazioni quando si interroga questa vista.

Problemi correlati