Relazione uno a molti - chiavi esterne, JOIN ed errori da evitare

Bruno De luca 30 giugno 2026
Confronto tra piani di esecuzione: prima e dopo l'eliminazione di un join, mostrando come un'operazione complessa con relazione uno a molti si semplifica.

Indice

Quando un cliente effettua più ordini, un autore pubblica diversi articoli o una categoria raccoglie molti prodotti, il database deve rappresentare un legame preciso tra i dati. La relazione uno a molti risolve proprio questo caso: mostra come progettare le tabelle, usare chiavi primarie ed esterne, scrivere query SQL corrette e prevenire gli errori che compromettono analisi e report.

La struttura 1:N collega un record padre a più record figli

  • Cardinalità 1:N significa che un elemento può essere associato a molti altri.
  • Il collegamento si realizza con una chiave esterna nella tabella dal lato molti.
  • Il vincolo FOREIGN KEY protegge l’integrità referenziale.
  • La relazione può essere obbligatoria o facoltativa, a seconda dell’uso di NULL.
  • Per i report BI, la struttura migliora filtri, aggregazioni e qualità dei dati.

Diagramma ERD e-commerce che illustra la relazione uno a molti tra clienti, ordini, prodotti e categorie.

Che cosa indica davvero la cardinalità 1:N

Il lato “uno” rappresenta l’entità padre, mentre il lato “molti” contiene le entità figlie. Un cliente può quindi avere molti ordini, ma ogni ordine appartiene normalmente a un solo cliente. La direzione inversa è spesso scritta come molti a uno, ma descrive lo stesso legame osservato dal punto di vista della tabella figlia.

Esempio Lato uno Lato molti
Clienti e ordini Un cliente Molti ordini
Categorie e prodotti Una categoria Molti prodotti
Autori e articoli Un autore Molti articoli
Reparti e dipendenti Un reparto Molti dipendenti

La cardinalità massima non dice necessariamente che ogni padre debba avere almeno un figlio. Un cliente appena registrato può avere zero ordini, mentre un cliente attivo può averne centinaia. Per questo conviene distinguere tra cardinalità minima e massima, ad esempio 0:N per un legame facoltativo oppure 1:N quando ogni elemento padre deve avere almeno un elemento collegato.

Nel modello entità-relazione questa struttura viene spesso disegnata con il simbolo “1” da una parte e la “zampa di gallina” dall’altra. Nella pratica, però, il diagramma è solo il punto di partenza: la regola deve essere tradotta correttamente nelle colonne e nei vincoli del database.

Come si costruisce con chiave primaria e chiave esterna

La tabella dal lato uno contiene una chiave primaria, cioè un valore univoco che identifica ogni record. La tabella dal lato molti ripete quel riferimento attraverso una chiave esterna, che collega ogni riga al record padre corretto.

Immaginiamo due tabelle semplici. La prima contiene i clienti, la seconda gli ordini. L’identificativo del cliente viene definito una sola volta nella tabella principale e utilizzato nella tabella degli ordini.

CREATE TABLE clienti (
    id_cliente INTEGER PRIMARY KEY,
    nome VARCHAR(100) NOT NULL,
    email VARCHAR(150) UNIQUE
);

CREATE TABLE ordini (
    id_ordine INTEGER PRIMARY KEY,
    data_ordine DATE NOT NULL,
    totale DECIMAL(10,2) NOT NULL,
    id_cliente INTEGER NOT NULL,
    FOREIGN KEY (id_cliente)
        REFERENCES clienti(id_cliente)
);

La clausola NOT NULL rende obbligatorio il collegamento. Se invece un ordine potesse essere importato temporaneamente senza cliente associato, la colonna potrebbe accettare NULL, ma questa scelta va motivata: lasciare riferimenti vuoti senza una regola chiara rende più fragili i report.

La query per leggere i dati collegati

Per ottenere il nome del cliente insieme ai suoi ordini si usa una JOIN. La condizione collega la chiave primaria di una tabella con la chiave esterna dell’altra.
SELECT
    c.nome,
    o.id_ordine,
    o.data_ordine,
    o.totale
FROM clienti AS c
INNER JOIN ordini AS o
    ON c.id_cliente = o.id_cliente;

Con INNER JOIN compaiono solo i clienti che hanno almeno un ordine. Se voglio includere anche i clienti senza acquisti, uso invece una LEFT JOIN.

SELECT
    c.nome,
    COUNT(o.id_ordine) AS numero_ordini,
    COALESCE(SUM(o.totale), 0) AS valore_totale
FROM clienti AS c
LEFT JOIN ordini AS o
    ON c.id_cliente = o.id_cliente
GROUP BY c.id_cliente, c.nome;

Questa differenza è piccola nella sintassi, ma enorme nell’analisi. Un INNER JOIN può eliminare dal risultato i clienti inattivi, mentre una LEFT JOIN conserva il lato padre e permette di misurare anche gli zeri.

Tre esempi che chiariscono quando usarla

Clienti e ordini

È il caso più intuitivo. Un cliente può effettuare molti ordini, ma ogni ordine deve riferirsi a un solo cliente. Il modello evita di ripetere nome, indirizzo ed email in ogni riga dell’ordine, riducendo la ridondanza e il rischio di aggiornare solo una parte delle informazioni.

Se lo stesso cliente cambia indirizzo, la modifica viene registrata nella tabella clienti. Gli ordini storici, però, potrebbero dover conservare l’indirizzo di spedizione usato al momento dell’acquisto. In questo caso non basta una relazione: serve anche decidere quali dati devono restare storici e quali devono riflettere sempre il valore attuale.

Categorie e prodotti

Una categoria come “Computer portatili” può contenere molti prodotti, mentre ogni prodotto appartiene a una sola categoria. È una struttura efficace per cataloghi, filtri e dashboard commerciali, soprattutto quando la categoria viene usata come dimensione di analisi.

Se un prodotto può appartenere contemporaneamente a più categorie, il modello non è più 1:N. Diventa molti a molti e richiede una tabella ponte, ad esempio prodotti_categorie, con una riga per ogni associazione.

Reparti e dipendenti

Un reparto può avere molti dipendenti e ogni dipendente può essere assegnato a un solo reparto. Qui la scelta più importante riguarda la partecipazione minima: un dipendente senza reparto potrebbe essere ammesso durante una fase di onboarding, oppure vietato da una regola organizzativa.

Questo esempio mostra perché non conviene progettare il database guardando soltanto le colonne. La domanda corretta è sempre legata al processo reale: quali associazioni sono possibili, obbligatorie e valide nel tempo?

Che cosa cambia nei report e nei formati dati

Una struttura ben modellata è utile anche fuori dal database operativo. In strumenti di business intelligence, la tabella dal lato uno assomiglia spesso a una dimensione, mentre quella dal lato molti contiene eventi o misure, come ordini, vendite e movimenti.

Nel modello analitico a stella, per esempio, una dimensione Cliente può collegarsi a una tabella dei fatti Vendite. Il rapporto consente di filtrare il fatturato per area, segmento o cliente senza duplicare tutte le descrizioni nella tabella degli eventi.

Formato Come rappresenta il legame Uso più adatto
Database SQL Chiave primaria e chiave esterna Dati transazionali e integrità
CSV Colonna ID ripetuta nelle righe figlie Scambi semplici e importazioni
JSON ID collegato oppure array di oggetti annidati API e applicazioni web
Power BI Relazione tra colonne con cardinalità 1:* Dashboard e analisi interattive

Nel JSON il legame può essere espresso in due modi. Si può conservare solo l’identificativo del padre, mantenendo una struttura normalizzata, oppure annidare un array di ordini dentro il cliente. L’annidamento è comodo per alcune API, ma può creare duplicazioni e payload pesanti quando lo stesso dato viene distribuito in molti contesti.

In Power BI la cardinalità deve riflettere i dati reali, non una supposizione. Se la colonna che dovrebbe essere univoca contiene duplicati, il modello può diventare ambiguo o produrre totali inattesi. Io controllo sempre unicità, valori nulli e direzione dei filtri prima di fidarmi di una misura.

Gli errori che compromettono il modello

Mettere la chiave esterna nella tabella sbagliata

Nel rapporto 1:N, il riferimento normalmente vive dal lato molti. Inserire l’elenco degli ordini in una colonna del cliente, magari separato da virgole, rende difficili ricerca, aggiornamento e controllo dei dati. È il classico segnale di una struttura non normalizzata.

Confondere identificativo e attributo descrittivo

Collegare le tabelle tramite il nome del cliente o della categoria sembra semplice, ma i nomi possono cambiare, contenere errori o non essere univoci. Una chiave surrogate numerica o un identificativo stabile è generalmente più sicuro per i collegamenti.

Ignorare cancellazioni e aggiornamenti

Quando si elimina un record padre, bisogna decidere cosa accade ai figli. Con ON DELETE CASCADE vengono eliminati anche i record collegati, una scelta comoda per dati temporanei ma rischiosa per ordini o fatture. Con ON DELETE RESTRICT si impedisce invece la cancellazione finché esistono dipendenze.

Per i dati finanziari preferisco quasi sempre conservare la storia e usare uno stato, come “annullato”, invece di cancellare fisicamente le righe. La soluzione corretta dipende da obblighi di conservazione, audit e logica applicativa.

Leggi anche: Da XML a Excel con Power Query - guida pratica

Usare una relazione 1:N quando serve una molti a molti

Un libro può avere più autori e un autore può scrivere più libri. Forzare questo caso in una singola chiave esterna porta a perdere informazioni oppure a creare colonne come autore_1, autore_2 e autore_3. La tabella ponte è più flessibile e permette di aggiungere attributi come il ruolo dell’autore o l’ordine di comparsa.

Come verificare che la relazione funzioni davvero

Prima di collegare il modello a un report, eseguo alcuni controlli semplici ma decisivi. Cerco chiavi esterne senza corrispondenza, duplicati sul lato uno e record figli privi di riferimento quando il campo dovrebbe essere obbligatorio.
SELECT o.id_ordine, o.id_cliente
FROM ordini AS o
LEFT JOIN clienti AS c
    ON o.id_cliente = c.id_cliente
WHERE c.id_cliente IS NULL;

Se la query restituisce righe, esistono ordini “orfani”. In un database con vincolo FOREIGN KEY non dovrebbero comparire, ma possono emergere durante importazioni, migrazioni o caricamenti da file CSV.

Controllo anche la distribuzione dei figli per ogni padre. Un cliente con migliaia di ordini potrebbe essere un caso reale, ma anche il risultato di un caricamento duplicato. Una verifica di qualità deve combinare vincoli tecnici e controlli sulle anomalie di business.

  • La chiave primaria del lato uno deve essere univoca.
  • La chiave esterna deve avere tipo compatibile con la chiave primaria.
  • I valori NULL devono rispettare la regola del processo.
  • Le colonne usate nei JOIN dovrebbero avere indici adeguati.
  • Le query aggregate devono gestire correttamente i record senza figli.

Una buona relazione rende più affidabile ogni analisi

La struttura 1:N non è soltanto una regola teorica di progettazione. È il modo più chiaro per collegare entità che appartengono allo stesso processo, mantenendo i dati coerenti e limitando la duplicazione.

La mia regola pratica è partire sempre dalla frase del dominio, ad esempio “un cliente può avere molti ordini”, e trasformarla in una verifica concreta su chiavi, vincoli e casi limite. Se il modello risponde bene anche a clienti senza ordini, record storici, cancellazioni e importazioni imperfette, allora sarà molto più solido anche quando arriveranno dashboard, API e nuovi formati di dati.

Domande frequenti

La chiave esterna va nella tabella dal lato molti e deve riferirsi alla chiave primaria della tabella padre. Ad esempio, ogni ordine contiene l’ID del cliente a cui appartiene. Il vincolo FOREIGN KEY impedisce riferimenti a clienti inesistenti.

La INNER JOIN restituisce solo i clienti che hanno almeno un ordine. La LEFT JOIN conserva anche i clienti senza ordini e consente di calcolare correttamente valori pari a zero con funzioni come COUNT e COALESCE.

Il modello cambia quando ogni elemento può essere associato a più elementi dell’altra tabella. Un libro con più autori, ad esempio, richiede una tabella ponte con una riga per ogni associazione, invece di una sola chiave esterna.

Occorre verificare l’univocità della chiave primaria, la compatibilità dei tipi, i valori NULL e la presenza di chiavi esterne senza corrispondenza. È inoltre utile controllare duplicati, record orfani e distribuzioni anomale dei figli per ogni record padre.

Valuta l'articolo

Valutazione: 0.00 Numero di voti: 0

Tag

cardinalità
chiavi esterne
normalizzazione
power bi
join
Autor Bruno De luca
Bruno De luca
Mi chiamo Bruno De Luca e da 9 anni mi dedico con passione all'analisi dei dati, alla Business Intelligence e alla Data Science. Quello che mi affascina di questo campo è la capacità di trasformare numeri grezzi in storie comprensibili, aiutando a prendere decisioni più informate e strategiche. Sul sito mondobi.it, il mio obiettivo è condividere conoscenze, semplificare concetti complessi e offrire prospettive aggiornate, basandomi su un approccio rigoroso di verifica delle fonti e organizzazione delle informazioni. Cerco sempre di rendere i contenuti accessibili e utili, per chiunque voglia navigare nel mondo dei dati con maggiore consapevolezza.

Condividi post

Scrivi un commento