Diagrammi Entità-Relazione: Una Guida Pratica alla Progettazione di Database
Impara a creare diagrammi ER per la modellazione di database. Copre entità, attributi, relazioni, cardinalità, notazione Chen vs Crow's Foot ed esempi di schema reali.
Uno schema di database scritto senza un diagramma è un'ipotesi. Si potrebbe ottenere le tabelle giuste al primo tentativo, ma quasi certamente si perderà una relazione, si posizionerà in modo errato una chiave esterna, o si costruirà una struttura che resiste alle query di cui l'applicazione ha effettivamente bisogno. I diagrammi entità-relazione — diagrammi ER — sono lo strumento standard per progettare e comunicare la struttura del database prima di scrivere una singola riga di SQL.
I diagrammi ER sono utili non solo per la progettazione iniziale ma durante l'intero ciclo di vita di un sistema: per l'inserimento di ingegneri che devono capire uno schema esistente, per la pianificazione delle migrazioni, per l'identificazione dei problemi di normalizzazione e per la documentazione del modello dati per gli stakeholder non tecnici.
Cos'è un diagramma ER?
Un diagramma ER (diagramma entità-relazione) è una rappresentazione visiva delle entità in un database e delle relazioni tra di esse. Mostra quali dati il sistema memorizza, quali attributi ha ogni entità e come le entità si relazionano tra loro.
Il concetto è stato introdotto da Peter Chen nel 1976 ed è stato esteso e adattato da strumenti e professionisti di database da allora. Due stili di notazione dominano la pratica moderna: la notazione Chen (progettazione concettuale) e la notazione Crow's Foot (orientata all'implementazione, utilizzata dalla maggior parte degli strumenti moderni).
I diagrammi ER operano a diversi livelli di astrazione:
| Livello | Scopo | Pubblico |
|---|---|---|
| Concettuale | Entità e relazioni ad alto livello | Stakeholder aziendali, PM |
| Logico | Attributi, chiavi, cardinalità aggiunti | Architetti di database |
| Fisico | Tipi di dati, indici, chiavi esterne, SQL-ready | Sviluppatori, DBA |
Concetti chiave
Entità
Un'entità è una cosa di cui il database memorizza informazioni. Si mappa a una tabella nel database implementato.
- Entità forte: Esiste in modo indipendente. Ha la propria chiave primaria. Esempio:
Customer,Product,Order - Entità debole: Dipende da un'altra entità per la sua esistenza. Esempio:
OrderLineItemdipende daOrder
Convenzioni di denominazione delle entità:
- Usare sostantivi singolari (
Order, nonOrders) - Il PascalCase è comune per i nomi delle entità
- Denominare ciò che la riga rappresenta, non la collezione
Attributi
Gli attributi sono proprietà di un'entità. Si mappano alle colonne nella tabella implementata.
| Tipo di Attributo | Descrizione | Esempio |
|---|---|---|
| Semplice | Valore singolo e atomico | firstName, price |
| Composto | Composto da sotto-attributi | address = street + city + zip |
| Derivato | Calcolato da altri attributi | age derivato da birthDate |
| Multi-valore | Può avere più valori | phoneNumbers (una persona può averne diversi) |
| Attributo chiave | Identifica univocamente un'istanza | customerId, email |
Nei diagrammi ER fisici, specificare i tipi di dati insieme ai nomi degli attributi:
Customer
├── customerId INT PRIMARY KEY
├── email VARCHAR(255) UNIQUE NOT NULL
├── firstName VARCHAR(100) NOT NULL
├── lastName VARCHAR(100) NOT NULL
├── createdAt TIMESTAMP DEFAULT NOW()
└── status ENUM('active', 'inactive', 'banned')
Relazioni
Una relazione definisce come due entità sono associate. Si mappa a un vincolo di chiave esterna (o a una tabella di giunzione per le relazioni molti-a-molti) nello schema implementato.
Le relazioni hanno:
- Nome: descrive l'associazione (
places,contains,belongs to) - Cardinalità: quante istanze di ogni entità possono partecipare
- Partecipazione: se la partecipazione è obbligatoria (totale) o opzionale (parziale)
Cardinalità
La cardinalità è il concetto più importante nella modellazione ER. Definisce la relazione numerica tra le istanze delle entità.
| Cardinalità | Significato | Esempio |
|---|---|---|
| Uno-a-Uno | Un'istanza A si relaziona a esattamente un'istanza B | User ha un Profile |
| Uno-a-Molti | Un'istanza A si relaziona a molte istanze B | Customer effettua molti Orders |
| Molti-a-Uno | Molte istanze A si relazionano a un'istanza B | Molti Orders appartengono a un Customer |
| Molti-a-Molti | Molte istanze A si relazionano a molte istanze B | Students si iscrivono a molti Courses |
Le relazioni molti-a-molti non possono essere implementate direttamente in un database relazionale. Richiedono una tabella di giunzione (detta anche join table o entità associativa):
Student ──< Enrollment >── Course
La tabella Enrollment contiene le chiavi esterne sia di Student che di Course, oltre a eventuali attributi dell'iscrizione stessa (come enrollmentDate o grade).
Stili di notazione
Notazione Chen
La notazione Chen è la notazione accademica originale. Utilizza forme geometriche:
- Rettangolo: Entità
- Ellisse: Attributo
- Rombo: Relazione
- Linea: Connessione
- Doppia ellisse: Attributo multi-valore
- Ellisse tratteggiata: Attributo derivato
- Doppio rettangolo: Entità debole
- Doppio rombo: Relazione di identificazione (per entità deboli)
Esempio ASCII di notazione Chen:
(customerId) (email) (firstName)
| | |
└─────────────┴───────────┘
|
┌─────────┐
│Customer │
└────┬────┘
│
< places >
│
┌─────────┐
│ Order │
└─────────┘
La notazione Chen è utile per la modellazione concettuale perché rende espliciti le relazioni e gli attributi. Diventa disordinata per gli schemi grandi.
Notazione Crow's Foot
La notazione Crow's Foot è lo stile dominante negli strumenti moderni di database (MySQL Workbench, dbdiagram.io, ERDPlus). Codifica la cardinalità direttamente sulla linea di relazione usando simboli a ciascuna estremità.
Simboli Crow's Foot:
Simbolo all'estremità Significato
───────────────────── ──────────────────────────────
──| Esattamente uno (obbligatorio)
──o Zero o uno (opzionale)
──< Molti (uno o più)
──o< Zero o più (molti opzionali)
──|< Uno o più (molti obbligatori)
──|| Esattamente uno (su entrambi i lati)
Esempio Crow's Foot — relazioni e-commerce:
Customer ||──o< Order ||──|< OrderLineItem >|──|| Product
Leggendo questo: un Customer ha zero o più Orders; ogni Order ha uno o più OrderLineItems; ogni OrderLineItem fa riferimento esattamente a un Product.
Entità completa con Crow's Foot:
┌─────────────┐ ┌─────────────┐ ┌──────────────────┐
│ Customer │ │ Order │ │ OrderLineItem │
│─────────────│ │─────────────│ │──────────────────│
│ PK id │||──o<─│ PK id │||──|<─│ PK id │
│ email │ │ FK customerId│ │ FK orderId │
│ name │ │ status │ │ FK productId │
│ createdAt│ │ total │ │ quantity │
└─────────────┘ │ createdAt│ │ unitPrice │
└─────────────┘ └──────────────────┘
La notazione Crow's Foot è preferita per i diagrammi ER logici e fisici perché è più compatta della notazione Chen e riflette direttamente la struttura dello schema SQL.
Il diagramma ER nel processo di progettazione del database
I diagrammi ER si inseriscono nella progettazione del database in più fasi:
1. Raccolta dei requisiti Lavorare con gli stakeholder per identificare le cose che il sistema deve tracciare. Ogni sostantivo nei requisiti è un'entità potenziale. Ogni fatto su un sostantivo è un attributo potenziale.
2. Progettazione concettuale Disegnare entità e relazioni senza preoccuparsi dei dettagli implementativi. Concentrarsi sul significato dei dati, non su come vengono memorizzati.
3. Progettazione logica Aggiungere attributi, definire chiavi primarie, risolvere le relazioni molti-a-molti in tabelle di giunzione, specificare la cardinalità.
4. Progettazione fisica Aggiungere tipi di dati, indici, vincoli e specifiche NULL/NOT NULL. Il diagramma ER in questa fase dovrebbe mapparsi direttamente all'SQL DDL.
5. Revisione e perfezionamento Validare lo schema rispetto alle query reali: si può recuperare in modo efficiente i dati di cui l'applicazione ha bisogno? Lo schema supporta tutte le operazioni richieste?
Guida alla creazione passo dopo passo
Passo 1: Identificare le entità
Leggere i requisiti o le user story ed evidenziare i sostantivi che rappresentano concetti distinti che il sistema traccia. Iniziare da quelli ovvi.
Per un sistema e-commerce:
- Customer, Product, Order, Category, Review, Address, Payment
Regole empiriche:
- Se ha più istanze, probabilmente è un'entità (non un attributo)
- Se ha i propri attributi, probabilmente è un'entità
- Se altre entità vi fanno riferimento in modo indipendente, è un'entità
Passo 2: Definire gli attributi per ogni entità
Per ogni entità, elencare le sue proprietà. Identificare:
- La chiave primaria (identificatore univoco, generato dal sistema o naturale)
- Attributi obbligatori (NOT NULL in SQL)
- Attributi opzionali
- Attributi che potrebbero essere composti (indirizzo) o multi-valore (tag)
Evitare di memorizzare dati derivati a meno che le prestazioni non lo richiedano. age è derivabile da birthDate; memorizzare entrambi crea problemi di coerenza.
Passo 3: Mappare le relazioni
Per ogni coppia di entità che interagisce, definire la relazione:
- Denominare la relazione (frase verbale dalla prospettiva di un'entità)
- Determinare la cardinalità (uno-a-uno, uno-a-molti, molti-a-molti)
- Determinare la partecipazione (ogni lato è obbligatorio o opzionale?)
Scriverla come frase e verificare che abbia senso in entrambe le direzioni:
- "Un Customer effettua zero o più Orders"
- "Un Order è effettuato da esattamente un Customer"
Passo 4: Risolvere le relazioni molti-a-molti
Ogni relazione molti-a-molti diventa una tabella di giunzione. Identificare gli attributi della relazione stessa (se presenti) — questi diventano colonne nella tabella di giunzione.
Student ──< Enrollment >── Course
Attributi di Enrollment:
- enrollmentDate
- grade
- status (active, withdrawn, completed)
Passo 5: Assegnare tipi di dati e vincoli
Per ogni attributo, specificare:
- Tipo di dati (
INT,VARCHAR(n),DECIMAL(10,2),TIMESTAMP,BOOLEAN) - NULL / NOT NULL
- Valori predefiniti
- Vincoli univoci
- Vincoli di controllo (es.
price > 0)
Passo 6: Validare rispetto alle query
Scrivere le query chiave che l'applicazione eseguirà e tracciarle attraverso lo schema. Se una query richiede più join che avrebbero potuto essere evitati con un design migliore, rivedere lo schema.
Controllare:
- Si può recuperare la cronologia completa degli ordini di un cliente?
- Si possono trovare tutti i prodotti in una categoria?
- Si possono calcolare i totali degli ordini dagli elementi di riga?
- Si possono generare report sui ricavi per intervallo di date?
Considerazioni sulla normalizzazione
La normalizzazione è il processo di strutturazione di uno schema per ridurre la ridondanza dei dati e migliorare l'integrità. Le tre forme normali più comunemente applicate:
Prima Forma Normale (1NF): Ogni colonna contiene valori atomici. Nessun gruppo ripetuto. Ogni riga è identificabile univocamente.
Seconda Forma Normale (2NF): Soddisfa la 1NF. Ogni attributo non-chiave dipende completamente dall'intera chiave primaria (rilevante per le chiavi composte).
Terza Forma Normale (3NF): Soddisfa la 2NF. Nessuna dipendenza transitiva — gli attributi non-chiave dipendono solo dalla chiave primaria, non da altri attributi non-chiave.
Esempio di violazione della 3NF: memorizzare customerCity nella tabella Order. La città dipende dal cliente, non dall'ordine. Se il cliente si sposta, si deve aggiornare ogni record dell'ordine.
Quando denormalizzare: La normalizzazione ottimizza per la coerenza in scrittura. I carichi di lavoro analitici ad alta lettura traggono talvolta vantaggio da strutture denormalizzate (viste materializzate, tabelle di reporting) che evitano costosi join. Prendere questa come una decisione deliberata, non un incidente.
Errori comuni
Usare chiavi naturali come chiavi primarie. Gli indirizzi email cambiano. I codici fiscali non dovrebbero essere memorizzati. I nomi non sono univoci. Usare chiavi surrogate (interi auto-incrementali o UUID) come chiavi primarie e aggiungere vincoli univoci agli identificatori naturali.
Memorizzare liste in una singola colonna. Una colonna tags contenente valori separati da virgole viola la 1NF. Usare invece una tabella di giunzione (ProductTag).
Attributi mancanti nella tabella di giunzione. Quando si risolve una relazione molti-a-molti, i team spesso creano una tabella di giunzione vuota con solo due chiavi esterne. Pensare agli attributi che appartengono alla relazione stessa — data di iscrizione, quantità dell'ordine, livello di autorizzazione.
Confondere entità e attributi. Address in un sistema semplice potrebbe essere attributi su Customer. In un sistema in cui più clienti condividono un indirizzo, o in cui gli indirizzi hanno il proprio ciclo di vita, Address dovrebbe essere un'entità separata.
Nessuna considerazione per le cancellazioni soft. Molti sistemi devono conservare i record dopo la "cancellazione" per ragioni di audit o normative. Decidere in anticipo se usare un timestamp deletedAt o un flag isActive e applicarlo in modo coerente.
Sovra-normalizzazione per dataset piccoli. Estrarre ogni stringa ripetuta in una tabella di lookup aggiunge complessità senza beneficio per dataset che non cresceranno mai oltre migliaia di righe. Applicare il giudizio, non regole meccaniche.
Ignorare la progettazione degli indici. Il diagramma ER mostra la struttura, non le prestazioni. Dopo aver finalizzato lo schema, identificare le colonne che verranno utilizzate nelle clausole WHERE e nelle condizioni JOIN e aggiungere indici ad esse.
Esempio reale: schema e-commerce
Il seguente schema copre le entità principali di un tipico sistema e-commerce.
┌──────────────┐ ┌──────────────┐ ┌───────────────────┐
│ Customer │ │ Order │ │ OrderLineItem │
│──────────────│ │──────────────│ │───────────────────│
│ PK id │ │ PK id │ │ PK id │
│ email │||─o<│ FK customerId│||─|<│ FK orderId │
│ firstName │ │ FK addressId │ │ FK productId │
│ lastName │ │ status │ │ quantity │
│ createdAt │ │ subtotal │ │ unitPrice │
│ status │ │ tax │ └────────┬──────────┘
└──────────────┘ │ shipping │ │
│ total │ esattamente uno
│ createdAt │ │
└──────────────┘ ┌────────┴──────────┐
│ Product │
┌──────────────┐ │───────────────────│
│ Address │ │ PK id │
│──────────────│ │ FK categoryId │
│ PK id │ │ name │
│ FK customerId│ │ description │
│ line1 │ │ sku │
│ line2 │ │ price │
│ city │ │ stockQty │
│ state │ │ isActive │
│ zip │ └────────┬──────────┘
│ country │ │
│ isDefault │ molti │ appartiene a
└──────────────┘ │ uno
┌────────┴──────────┐
┌──────────────┐ │ Category │
│ Payment │ │───────────────────│
│──────────────│ │ PK id │
│ PK id │ │ FK parentId │
│ FK orderId │ │ name │
│ method │ │ slug │
│ amount │ └───────────────────┘
│ status │
│ processedAt│
└──────────────┘
Decisioni di design chiave in questo schema:
Addressè un'entità separata (i clienti possono avere più indirizzi; gli ordini fanno riferimento all'indirizzo usato al momento dell'acquisto)OrderLineItem.unitPriceè memorizzato separatamente daProduct.price(i prezzi cambiano; la cronologia degli ordini deve riflettere ciò che è stato addebitato)Categoryha unparentIdauto-referenziale per categorie gerarchichePaymentè separato daOrderperché un ordine potrebbe comportare più tentativi di pagamento
Creare diagrammi ER con Flowova
Progettare uno schema a mano o in un editor di testo normale è lento. Il generatore di diagrammi ER di Flowova consente di descrivere il modello dati in linguaggio naturale e produce un diagramma strutturato da perfezionare. Iniziare con la lista delle entità, descrivere le relazioni tra di esse e ottenere uno schema visivo da condividere con il team per la revisione.
Conclusione
I diagrammi ER sono il fondamento della buona progettazione del database. Costringono ad essere espliciti su quali dati il sistema memorizza, cosa rende univoco ogni record e come le entità si relazionano tra loro — prima che queste decisioni diventino costose da cambiare in SQL. Iniziare a livello concettuale con entità e relazioni, passare al livello logico aggiungendo attributi e risolvendo i join molti-a-molti, poi aggiungere tipi di dati e vincoli per la progettazione fisica. Validare rispetto alle query reali, applicare la normalizzazione dove conta e documentare lo schema in modo che il prossimo ingegnere possa capirlo senza leggere i file di migrazione.
Risorse correlate
- Simboli e Significati del Diagramma di Flusso — Riferimento per la notazione standard
- Tipi di Diagrammi di Flusso — Quando usare diversi tipi di diagramma
- Guida ai Diagrammi di Sequenza — Modella le interazioni di sistema
- Generatore di Diagrammi ER — Crea diagrammi ER con l'AI
