▦ Dati e database

Anagrafiche duplicate: come trovarle e unirle senza perdere dati

Normalizzazione, chiavi di confronto, somiglianza tra stringhe e fusione: un metodo pratico per eliminare i clienti duplicati da un database.

Quasi ogni anagrafica clienti che abbia qualche anno contiene duplicati. Lo stesso cliente registrato dal negozio fisico e dal sito, con il nome scritto in due modi diversi; un'azienda inserita una volta con la ragione sociale completa e una con la sigla; una persona che ha cambiato email e si è registrata di nuovo. I duplicati gonfiano il numero di clienti, dividono la storia degli acquisti, fanno arrivare due volte la stessa comunicazione. Eliminarli richiede metodo, perché unire per errore due persone diverse è peggio che lasciarle separate.

Perché i duplicati non sono uguali

Raramente due record duplicati sono identici. Più spesso differiscono per dettagli:

Campo Record 1 Record 2
Nome Giuseppe Esposito ESPOSITO GIUSEPPE
Email g.esposito@esempio.it G.Esposito@Esempio.it
Telefono 333 123 4567 +393331234567
Indirizzo Via Roma 12 V. Roma, 12

Un confronto esatto non trova nulla. Il lavoro si divide quindi in tre fasi: rendere confrontabili i valori, individuare i candidati, decidere e unire.

Fase 1: normalizzare

Normalizzare significa trasformare ogni valore in una forma standard, senza modificare i dati originali: si creano colonne di appoggio o una tabella separata.

  • Testo: minuscole, spazi multipli ridotti a uno, spazi iniziali e finali tolti, accenti eventualmente rimossi per il confronto.
  • Email: minuscole e senza spazi.
  • Telefoni: solo cifre, con il prefisso internazionale aggiunto in modo uniforme.
  • Indirizzi: abbreviazioni ricondotte a una forma unica («V.» e «Via» diventano «via»), punteggiatura rimossa.
  • Nomi: parole ordinate alfabeticamente, così «Esposito Giuseppe» e «Giuseppe Esposito» coincidono.
SELECT id,
       LOWER(TRIM(email)) AS email_norm,
       REGEXP_REPLACE(telefono, '[^0-9]', '', 'g') AS tel_norm
FROM clienti;

La sintassi delle espressioni regolari varia tra i database; in alternativa la normalizzazione si fa con uno script.

Fase 2: trovare i candidati

Corrispondenze esatte sui valori normalizzati

Il primo passaggio, il più affidabile, cerca record con lo stesso valore normalizzato su un campo fortemente identificativo: email, codice fiscale, partita IVA, telefono cellulare.

SELECT email_norm, ARRAY_AGG(id) AS ids
FROM clienti_norm
GROUP BY email_norm
HAVING COUNT(*) > 1;

Corrispondenze approssimate

Per nomi e indirizzi servono misure di somiglianza. Le più usate sono:

  • distanza di Levenshtein: il numero minimo di caratteri da inserire, cancellare o sostituire per passare da una stringa all'altra. «Rossi» e «Rosi» hanno distanza 1;
  • somiglianza per trigrammi: si scompongono le stringhe in gruppi di tre caratteri e si misura quanti ne hanno in comune. PostgreSQL la offre con l'estensione pg_trgm;
  • codifiche fonetiche, che assegnano lo stesso codice a parole che suonano simili. Gli algoritmi più noti sono pensati per l'inglese e funzionano male con i cognomi italiani.

Confrontare ogni record con tutti gli altri diventa rapidamente impraticabile: con 100.000 clienti le coppie sono quasi cinque miliardi. Si usa quindi una chiave di blocco: si confrontano solo i record che condividono qualcosa di semplice, come lo stesso CAP o le stesse prime tre lettere del cognome normalizzato. Il numero di confronti si riduce drasticamente.

Combinare più indizi

Un singolo campo simile non basta. Due persone diverse possono chiamarsi Giuseppe Esposito e vivere nella stessa città. Conviene assegnare un punteggio:

  • email uguale: indizio forte;
  • telefono uguale: indizio forte;
  • nome molto simile e stesso indirizzo: indizio forte;
  • nome simile e stessa città: indizio debole.

Le coppie con punteggio alto si uniscono, quelle intermedie vanno riviste da una persona, quelle basse si scartano.

Fase 3: unire

La fusione è la parte più delicata, e va pensata prima di toccare i dati.

  1. Scegliere il record principale, di solito il più vecchio o il più completo.
  2. Decidere campo per campo quale valore tenere: il più recente, il più completo, quello verificato.
  3. Spostare i riferimenti: ordini, fatture, ticket e consensi del record secondario vanno aggiornati perché puntino al principale.
  4. Non cancellare subito il secondario: si marca come unito, conservando un riferimento al principale. Se la fusione era sbagliata, si può tornare indietro.
  5. Registrare l'operazione in una tabella di storico: quali record, quando, con quale criterio.
BEGIN;
UPDATE ordini SET id_cliente = 101 WHERE id_cliente = 245;
UPDATE ticket SET id_cliente = 101 WHERE id_cliente = 245;
UPDATE clienti SET unito_in = 101, attivo = false WHERE id = 245;
INSERT INTO storico_fusioni (principale, secondario, eseguita_il, criterio)
VALUES (101, 245, now(), 'email uguale');
COMMIT;

Tutto dentro una transazione, così un errore a metà non lascia ordini sparsi tra due record.

Attenzione ai consensi privacy: se un record ha revocato il consenso alle comunicazioni e l'altro no, dopo la fusione deve prevalere la scelta più restrittiva o più recente, non quella che fa comodo.

Prevenire i nuovi duplicati

Ripulire una volta non basta se le cause restano. Le contromisure più efficaci:

  • vincoli UNIQUE sui valori normalizzati, come l'email in minuscolo;
  • ricerca dei clienti simili prima di crearne uno nuovo, nelle interfacce usate dal personale;
  • un unico punto di creazione dei clienti, invece di più sistemi che li creano ciascuno per conto proprio.

In sintesi

  • I duplicati reali differiscono per dettagli: prima si normalizzano i valori.
  • Le corrispondenze esatte su campi forti sono il primo passaggio, il più sicuro.
  • Per nomi e indirizzi servono misure di somiglianza e chiavi di blocco.
  • La fusione sposta i riferimenti, conserva il record secondario e registra l'operazione.
  • Vincoli e ricerche preventive impediscono che i duplicati si riformino.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica e in psicologia, unisce l'analisi tecnica alla comprensione del fattore umano.

Leggi anche