Come si modella la realtà con lo schema E/R - esempio vendita di piante
Dalla traccia alla progettazione concettuale: analizziamo insieme un caso reale (vivai, clienti, fornitori, listini storici) e costruiamo lo schema E/R senza perdere nulla. Con tip da verifica.
1. Lo scenario: cosa ci chiede il problema
Progettare un DB per gestione vendita piante: specie (codice univoco, nome latino, nome comune, da giardino sì/no, esotica sì/no, verde o fiorita), clienti (codice cliente, privati con nome+indirizzo, rivendite con p.iva+nome+indirizzo), fornitori (codice, nome, CF, indirizzo, fornisce più specie ma stessa specie sempre dallo stesso fornitore), acquisti (data, quantità, specie), listino prezzi storico per specie.
Questa traccia sembra semplice ma nasconde tutte le trappole classiche: un booleano doppio, una specializzazione, un vincolo 1:N mascherato, un prezzo che non può stare in SPECIE e un acquisto che sembra un'associazione.
Quando leggi la traccia, sottolinea con 3 colori: BLU le entità candidate, GIALLO gli attributi, VERDE i verbi che diventeranno associazioni. Se un verbo ha attributi (data, quantità) -> è quasi sempre entità autonoma. Te lo chiedo sempre in verifica.
2. Analisi preliminare: i 5 aspetti da gestire
Il sistema deve gestire cinque macro-aree. Io in classe le faccio sempre scrivere prima di disegnare qualsiasi rettangolo:
Specie di piante
nome latino, comune, codice, caratteristiche stabili
Clienti + Fornitori
Privati vs Rivendite, specializzazione totale/esclusiva
Acquisti
Evento storico: cliente + specie + data + quantità
Listino prezzi
Non un attributo! Serve entità con intervallo temporale
Dati stabili vs variabili
Codici stabili, prezzi variabili: richiede entità diverse
8 passi concettuali
Entità → Associazioni → Attributi → Molteplicità → Verifica
Pensa al vivaio sotto casa: ha il cartellino della pianta (SPECIE), il fornitore che gliela porta (FORNITORE), te che la compri (CLIENTE), lo scontrino (ACQUISTO) e il cartello del prezzo che cambia a primavera (PREZZO_LISTINO). Se riesci a raccontarlo a voce, sai modellarlo.
3. Individuazione dei vincoli + ipotesi aggiuntive
A. Vincoli specie
- Codice univoco identificativo
- Nome latino + nome comune obbligatori
- da_giardino boolean, esotica boolean
- tipo_pianta: Verde o Fiorita - ipotesi mia: ogni specie appartiene a UNA sola categoria (semplificazione dichiarata)
Mettere "verde" e "fiorita" come due booleani separati. Così una pianta potrebbe risultare verde E fiorita E né verde né fiorita. Usa un attributo singolo tipo_pianta con dominio {Verde, Fiorita}.
B. Vincoli clienti
- Codice cliente univoco, comune a privati e rivendite
- PRIVATO: nome, indirizzo
- RIVENDITA: nome, indirizzo, p.iva
CLIENTE come generalizzazione totale ed esclusiva: ogni cliente DEVE essere privato O rivendita, non può essere entrambi, non può essere nessuno. Lo scrivete sempre nella relazione: "specializzazione T,E". Se lo omettete, per me il modello è incompleto.
C. Vincoli fornitori - il vincolo chiave
"La stessa specie è fornita sempre dallo stesso fornitore" → significa FORNITORE (0,n) --- (1,1) SPECIE. È un 1:N, NON N:M. Se sbagli questo, sbagli tutto lo schema.
D. Acquisti
Ogni acquisto: un cliente, una data, una specie, una quantità. Secondo testo: un acquisto riguarda UNA sola specie.
E. Listino prezzi
Prezzo NON in SPECIE. Perché? Perché perderesti lo storico. Serve entità PREZZO_LISTINO con data_inizio, data_fine (nullable), importo.
Ipotesi aggiuntive (dichiarate!)
| Ipotesi | Perché la introduco | Alternativa |
|---|---|---|
| codice_acquisto in ACQUISTO | Cliente+data+specie non è chiave: stesso cliente può comprare stessa specie 2 volte lo stesso giorno | Chiave composta rischiosa |
| prezzo_applicato in ACQUISTO | Per non perdere prezzo reale se listino cambia dopo | Non obbligatorio ma furbo - te lo premio |
| codice_prezzo in PREZZO_LISTINO | Identifica versioni temporali | Alternativa: (codice_specie, data_inizio) come chiave |
| nome, indirizzo in CLIENTE | Evita duplicazione in sottotipi | Mettere tutto nei sottotipi = ridondanza |
Univocità: codici unici
Esistenza: acquisto → cliente e specie esistenti
Coerenza temporale: data_fine ≥ data_inizio
No sovrapposizioni: per stessa specie non due listini validi nello stesso periodo
Coerenza sottotipo: un cliente = un solo sottotipo
Quantità >0
4. Le entità: perché Acquisto e Prezzo sono entità
Nel nostro schema finale abbiamo 5 entità principali + 2 sottotipi:
SPECIE
Esempi: Rosa, Lavanda, Ficus. Attributi identificativi + booleani + tipo
CLIENTE (gen.)
Generalizzazione. Partecipa a EFFETTUA. Totale Esclusiva → PRIVATO, RIVENDITA
FORNITORE
Codice, nome, CF, indirizzo. Fornisce N specie.
ACQUISTO
Perché è entità? Ha attributi propri (data, quantità, prezzo_applicato) ed è evento storico. Se fosse solo associazione tra CLIENTE e SPECIE non potresti avere stesso cliente+specie in date diverse.
PREZZO_LISTINO
Perché è entità? Un attributo prezzo in SPECIE terrebbe solo prezzo corrente. Qui: Rosa 5€ dal 1/1 al 31/3, 5.5€ dal 1/4... storico.
PRIVATO / RIVENDITA
Ereditano codice_cliente. PRIVATO non aggiunge nulla di obbligatorio, RIVENDITA aggiunge p.iva. Non creare associazioni separate per acquisti.
"Prof, ACQUISTO non è un'associazione?" Risposta che voglio sentire: "No, perché ha attributi propri e deve esistere come oggetto storico distinguibile, con identificatore proprio. Altrimenti non potrei registrare due acquisti identici in giorni diversi." Scrivetelo così in verifica.
5. Associazioni e specializzazione
Quattro associazioni + una specializzazione:
Molti disegnano FORNITORE - SPECIE come N:M "perché un fornitore fornisce più specie e una specie può essere fornita da più fornitori". Ma la traccia dice ESPLICITAMENTE il contrario: stessa specie SEMPRE dallo stesso fornitore. È 1:N. Leggete il vincolo, non inventate.
6. Attributi: cosa mettere dove (e cosa NON duplicare)
SPECIE
Identificatore {PK}: codice_specie (non nome comune! I nomi comuni non sono univoci e cambiano). Altri: nome_latino, nome_comune, da_giardino {Sì/No}, esotica {Sì/No}, tipo_pianta {Verde, Fiorita}
CLIENTE (soluzione compatta che preferisco)
Identificatore {PK}: codice_cliente, nome, indirizzo → comuni a tutti. PRIVATO: eredita tutto, nessun attributo aggiuntivo obbligatorio. RIVENDITA: partita_IVA. Così eviti duplicazione nome/indirizzo.
Variante ammessa: mettere nome e indirizzo solo nei sottotipi. È corretta ma ridondante. Io premio la soluzione compatta perché dimostra che hai capito l'ereditarietà. Se metti nome in CLIENTE e lo ripeti anche in PRIVATO, è errore di ridondanza.
FORNITORE
Identificatore {PK}: codice_fornitore, nome, codice_fiscale, indirizzo.
ACQUISTO
Identificatore {PK}: codice_acquisto (introdotto da noi), data_acquisto, quantita, prezzo_applicato (opzionale ma intelligente). Non usare come chiave (cliente+data+specie): fallisce se compri due volte stessa specie lo stesso giorno.
Non creare ACQUISTO_PRIVATO e ACQUISTO_RIVENDITA. Gli acquisti sono legati a CLIENTE generale. La specializzazione eredita già l'associazione. Doppia associazione = schema sporco.
PREZZO_LISTINO
Identificatore {PK}:: codice_prezzo, importo, data_inizio_validita, data_fine_validita (NULL se ancora valido). Alternativa chiave: (codice_specie, data_inizio) se imponi un solo prezzo per data inizio.
Quantità NON è attributo di EFFETTUA, è di ACQUISTO. Prezzo NON è attributo di APPARTENERE, è di PREZZO_LISTINO. Se mettete attributi sulle associazioni, il modello diventa ambiguo.
7. Molteplicità e cardinalità con regole di lettura
Uso notazione (min,max): (0,1) facoltativo al max 1, (1,1) obbligatorio esattamente 1, (0,n) facoltativo n, (1,n) obbligatorio almeno 1.
| Associazione | Molteplicità | Cardinalità | Perché min=0 o 1? |
|---|---|---|---|
| FORNIRE FORNITORE-SPECIE | FORNITORE (0,n) — (1,1) SPECIE | 1:N | Fornitore (0,n): appena inserito può non avere specie fornite. Specie (1,1): ogni specie deve avere fornitore. |
| EFFETTUARE CLIENTE-ACQUISTO | CLIENTE (0,n) — (1,1) ACQUISTO | 1:N | Cliente può non aver ancora comprato. Acquisto non esiste senza cliente. |
| RIGUARDARE ACQUISTO-SPECIE | ACQUISTO (1,1) — (0,n) SPECIE | N:1 | Acquisto riguarda 1 specie. Specie può non essere mai stata acquistata. |
| APPARTENERE SPECIE-PREZZO | SPECIE (0,n) — (1,1) PREZZO | 1:N | Specie inserita prima di avere prezzo. Prezzo deve appartenere a 1 specie. |
Totale: ogni cliente è privato o rivendita (esaustiva). Esclusiva: non può essere entrambi. Deriva da ipotesi che categorie siano alternative ed esaustive nel testo.
Molti disegnano FORNITORE - SPECIE come N:M "perché un fornitore fornisce più specie e una specie può essere fornita da più fornitori". Ma la traccia dice ESPLICITAMENTE il contrario: stessa specie SEMPRE dallo stesso fornitore. È 1:N. Leggete il vincolo, non inventate.
Regole di lettura (le voglio così in verifica!)
Se in verifica scrivete solo "1:N" senza min e max, per me è incompleto. Voglio vedere (0,N) vs (1,1) con motivazione del minimo. Il minimo racconta se l'entità può esistere senza l'altra. È lì che si vede se avete capito la realtà, non solo la teoria.
8. Schema E/R finale
TUTTE LE ENTITA' rettangoli con nome all'interno, {PK} con terminale pieno + attributi con terminale vuoto collegati al rettangolo e nominati
TUTTE LE ASSOCIAZIONI molteplicità indicate sul collegamento ENTITA'- ASSOCIAZIONE lato entità
TUTTE LE SPECIALIZZAZIONI con doppio segmento verso cerchio all'interno del quale si indica T/E → specializzazione (rettangolo come entità) collegata al cerchio da un segmento indicante E
9. Errori comuni e checklist finale (da stampare)
1. Prezzo in SPECIE → perdi storico
2. ACQUISTO come associazione N:M tra CLIENTE e SPECIE → non puoi registrare 2 acquisti uguali in giorni diversi
3. FORNISCE N:M → viola vincolo "stessa specie sempre stesso fornitore"
4. Due entità CLIENTE_PRIVATO e CLIENTE_RIVENDITA separate senza generalizzazione → duplichi associazioni
5. Quantità come attributo di CLIENTE o di SPECIE → non descrive l'evento acquisto
| Check | Domanda | Se NO, cosa fare |
|---|---|---|
| Entità | Ogni entità ha identificatore? | Aggiungi codice_acquisto, codice_prezzo |
| Specializzazione | Ho dichiarato T,E? | Scrivi "Totale Esclusiva" |
| Fornitore | SPECIE ha (1,1) verso FORNITORE? | Correggi molteplicità |
| Storico | Posso avere più prezzi per stessa specie? | Se no, hai messo prezzo in SPECIE |
| Sovrapposizioni | Ho previsto vincolo no-overlap date? | Annota nei vincoli di integrità |
| Lettura | Riesco a leggere schema ad alta voce? | Se inciampi, lo schema è sbagliato |
In verifica non guardo solo il disegno. Voglio: 1) vincoli scritti, 2) ipotesi dichiarate, 3) molteplicità con min/max, 4) regole di lettura, 5) identificatori visibili. Se manca uno di questi, anche se il disegno è bello, non è da 10. Questo articolo è fatto affinchè possiate allenarvi a consegnare tutto.

