Prima di tradurre il modello E-R in schema logico, è necessario ristrutturarlo: eliminare o trasformare i costrutti che i database relazionali standard non supportano direttamente.
I DBMS relazionali non gestiscono nativamente l’ereditarietà. Esistono tre strategie:
Strategia A — Accorpamento verso l’alto (nel padre): Tutti gli attributi dei figli vengono portati nella tabella del padre. Si aggiunge una colonna discriminatrice per distinguere i tipi.
-- Padre: Persona. Figli: Studente, Docente
CREATE TABLE persone (
id_persona INT PRIMARY KEY,
nome VARCHAR(50) NOT NULL,
cognome VARCHAR(50) NOT NULL,
tipo ENUM('studente', 'docente') NOT NULL,
matricola VARCHAR(10), -- solo per studenti, NULL per docenti
stipendio DECIMAL(8,2) -- solo per docenti, NULL per studenti
);
✓ Un’unica tabella, query semplici per trovare tutte le persone. ✗ Molti valori NULL, semantica meno chiara.
Strategia B — Accorpamento verso il basso (nei figli): Il padre sparisce. Le sue proprietà vengono duplicate in ogni tabella figlia.
CREATE TABLE studenti (
id_studente INT PRIMARY KEY,
nome VARCHAR(50), -- duplicato dal padre
cognome VARCHAR(50), -- duplicato dal padre
matricola VARCHAR(10)
);
CREATE TABLE docenti (
id_docente INT PRIMARY KEY,
nome VARCHAR(50), -- duplicato dal padre
cognome VARCHAR(50), -- duplicato dal padre
stipendio DECIMAL(8,2)
);
✓ Tabelle compatte, nessun NULL. ✗ Attributi comuni duplicati, difficile fare query su tutte le persone.
Strategia C — Identità separate (relazioni 1:1): Si mantengono sia padre che figli, collegati con FK. È la soluzione più flessibile.
CREATE TABLE persone (
id_persona INT PRIMARY KEY,
nome VARCHAR(50) NOT NULL,
cognome VARCHAR(50) NOT NULL
);
CREATE TABLE studenti (
id_studente INT PRIMARY KEY,
id_persona INT NOT NULL UNIQUE,
matricola VARCHAR(10),
FOREIGN KEY (id_persona) REFERENCES persone(id_persona)
);
CREATE TABLE docenti (
id_docente INT PRIMARY KEY,
id_persona INT NOT NULL UNIQUE,
stipendio DECIMAL(8,2),
FOREIGN KEY (id_persona) REFERENCES persone(id_persona)
);
✓ Massima flessibilità, dati ben separati, nessuna ridondanza. ✗ Richiede JOIN per ottenere i dati completi.
Gli attributi multivalore diventano sempre una tabella separata con relazione 1:N.
-- Prima: studenti con attributo multivalore "lingue_parlate"
-- Dopo:
lingue_studente (id (pk), id_studente (fk), lingua VARCHAR(50))
Gli attributi composti vengono “esplosi” in attributi semplici.
-- Prima: attributo "indirizzo" composto da via, civico, CAP, città
-- Dopo: quattro colonne separate nella stessa tabella