guidetutorialreferencedevopsflowchart-basics

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.

10 min di lettura

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: OrderLineItem dipende da Order

Convenzioni di denominazione delle entità:

  • Usare sostantivi singolari (Order, non Orders)
  • 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:

  1. Denominare la relazione (frase verbale dalla prospettiva di un'entità)
  2. Determinare la cardinalità (uno-a-uno, uno-a-molti, molti-a-molti)
  3. 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 da Product.price (i prezzi cambiano; la cronologia degli ordini deve riflettere ciò che è stato addebitato)
  • Category ha un parentId auto-referenziale per categorie gerarchiche
  • Payment è separato da Order perché 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

Articoli correlati

Pronto a Provare il Generatore di Diagrammi di Flusso AI?

Unisciti a decine di migliaia di professionisti che usano Flowova per visualizzare le loro idee. Inizia a creare diagrammi di flusso con l'AI in pochi secondi.

Inizia Gratis