Esercizio - Progettazione ER e schema relazionale del social network (esercizio social e laboratorio)
In questa pagina 6
Testo (esercizio di modellazione ER "social network" e laboratorio, corso di Basi di Dati, Ing. Informatica UniPD). Si vuole sviluppare una piattaforma social in cui ogni utente registrato può creare uno o più post. Un utente può anche rispondere a un post con un commento, oppure rispondere a un commento già presente. Un post può avere più commenti, così come un commento può ricevere a sua volta più risposte. Gli utenti si registrano fornendo email e password e possono seguirsi a vicenda. Infine si tiene traccia della data e ora in cui sono scritti post e messaggi. Il laboratorio aggiunge username, data di iscrizione e visibilità del post (pubblico, privato, amici).
Teoria: Modello entità-relazione - entità, relazioni e attributiIl modello entità-relazione (ER, Chen 1976) descrive il mini-mondo con entità (classi di oggetti autonomi), relazioni (associazioni tra due o più entità, di grado 2 o più) e attributi (proprietà locali di entità o relazioni su un dominio; NULL per l'informazione mancante, con tre significati; attributi composti). Ogni costrutto ha una semantica estensionale: un'entità è un insieme di oggetti (senza ripetizioni né ordine), una relazione è un sottoinsieme del prodotto cartesiano delle entità coinvolte (quindi la stessa coppia non può comparire due volte: per gli eventi ripetuti si introduce una nuova entità, come Sessione o Fattura), un attributo è una funzione totale dalle istanze a un dominio. Si sceglie un'entità invece di un attributo quando il concetto ha istanze con proprietà proprie o collegamenti; mai trasformare un'entità in relazione. Lo schema ER è documentato dal dizionario dei dati (entità, relazioni, attributi, vincoli esterni).Modello entità-relazione - entità, relazioni e attributi →, Relazioni ricorsive, cardinalità e vincoli di integrità nel modello ERI vincoli di integrità di uno schema ER sono di quattro tipi: di cardinalità sulle relazioni, di cardinalità sugli attributi, di identificazione sulle entità e vincoli esterni. La cardinalità (min,max) di un'entità e con ruolo u in una relazione r dice a quante istanze di r partecipa ogni istanza di e: min 0 = partecipazione opzionale, min 1 = obbligatoria, max 1 = al più una volta, max N = molte; le relazioni binarie si classificano per i massimi in uno-a-uno, uno-a-molti, molti-a-molti. I vincoli di cardinalità non permettono di violare la semantica estensionale (una coppia compare una volta sola). Una relazione ricorsiva collega un'entità con se stessa e richiede i ruoli (Predecessore e Successore, Sorgente e Destinazione): con le cardinalità si ottengono catene, alberi e grafi diretti; grafi non diretti, assenza di cicli e di cappi richiedono vincoli esterni; i multigrafi si modellano con una terza entità (etichetta, colore). Gli attributi hanno cardinalità (1,1) di default, (0,1) se opzionali, (x,N) se multivalore.Relazioni ricorsive, cardinalità e vincoli di integrità nel modello ER →, Ristrutturazione dello schema ER e traduzione nel modello relazionaleLa progettazione logica ha due passi. 1) Ristrutturazione dello schema ER, per togliere i costrutti che il modello relazionale non esprime: analisi delle ridondanze (attributi derivati e cicli di relazioni, decisa con volume dei dati e carico, tabelle di frequenza e accessi), eliminazione degli attributi multivalore (nuova entità), composti (appiattiti o nuova entità), delle IS-A (relazione con partecipazione (1,1) dalla sottoclasse) e delle generalizzazioni (opzione 1 relazioni, 2 accorpamento nel padre con attributo discriminante, 3 accorpamento nei figli, solo se completa e disgiunta), scelta degli identificatori principali (niente cicli di identificazione esterna), riscrittura dei vincoli esterni, partizionamento e accorpamento di entità. 2) Traduzione quasi automatica nel modello relazionale: ogni entità diventa una relazione con la chiave primaria data dall'identificatore principale (anche esterno); una relazione molti-a-molti diventa una relazione con le chiavi delle entità; una uno-a-molti con partecipazione obbligatoria si fonde con l'entità dal lato max 1 con una chiave esterna; con partecipazione opzionale si fonde (NULL) o si crea una relazione a parte; le uno-a-uno si fondono sul lato con partecipazione obbligatoria; le ternarie seguono la stessa logica con le chiavi di tutte le entità.Ristrutturazione dello schema ER e traduzione nel modello relazionale →.
1. Analisi dei requisiti
Frasi filtrate, per concetto:
| Concetto | Frasi |
|---|---|
| Utente | si registra con email e password; ha uno username e una data di iscrizione; segue altri utenti (e può essere seguito) |
| Post | creato da un utente in una data e ora; ha un testo e una visibilità (public, private, friends) |
| Commento | scritto da un utente in una data e ora; ha un testo; appartiene a un post; può rispondere a un altro commento |
Scelte di modellazione:
- Utente, Post, Commento sono entità: hanno identità e proprietà proprie. "Messaggi" nel testo significa i commenti.
- Seguire è un legame tra utenti: relazione ricorsiva su Utente, con ruoli Follower e Followed, molti-a-molti.
- Un commento risponde a un post oppure a un commento. Il corso sceglie: ogni commento appartiene a un post e, se è una risposta, ha anche un commento di origine. Il vantaggio è che ogni commento conosce subito il suo post, senza risalire la catena.
- La data e ora è una proprietà dell'azione (chi ha scritto, quando), quindi attributo delle relazioni Pubblica e Scrive.
2. Schema ER
| Entità | Attributi |
|---|---|
| Utente | Email, Password, Username, Subscription_Date |
| Post | ID, Testo, Visibilita |
| Commento | ID, Testo |
| Relazione | Entità coinvolte (min,max) | Attributi |
|---|---|---|
| Segue | Utente ruolo Follower (0,N), Utente ruolo Followed (0,N) | |
| Pubblica | Utente (0,N), Post (1,1) | Data_Ora |
| Scrive (ternaria) | Utente (0,N), Post (0,N), Commento (1,1) | Data_Ora |
| Risponde | Commento ruolo Commento_Origine (0,N), Commento ruolo Commento_Risposta (0,1) |
Lettura delle cardinalità:
- Pubblica: ogni post ha esattamente un autore (1,1); un utente può non aver pubblicato nulla (0,N).
- Scrive: ogni commento è associato a una sola tripla (utente, post, commento): ha un autore e un post (1,1); un utente può non aver commentato, un post può non avere commenti (0,N).
- Risponde: un commento ha al più un commento di origine (0,1), ma può riceverne molte risposte (0,N): un albero di risposte. I commenti di primo livello non hanno origine.
- Segue: tutti (0,N): si può seguire nessuno e non essere seguiti.
Perché una ternaria? Scrive lega tre concetti insieme e il commento ha (1,1): conoscere il commento determina utente e post. È equivalente a due relazioni binarie (1,1) con Data_Ora attributo del commento; la ternaria mostra che l'azione "scrivere" ha tre partecipanti.
Vincoli esterni.
- Un utente non segue se stesso: Follower Followed.
- Una risposta appartiene allo stesso post del commento a cui risponde.
- La data e ora di un commento non precede quella del post, né quella del commento di origine.
- Username unico (chiave candidata di Utente oltre all'email).
- Visibilita ammette solo public, private, friends.
3. Ristrutturazione
Nessun attributo multivalore, composto o derivato, nessuna generalizzazione. Gli identificatori sono già principali: Email per Utente (interno), ID per Post e Commento (serial, senza significato). Le relazioni Pubblica e Scrive hanno già la forma giusta per la fusione.
4. Schema relazionale
Chiave primaria sottolineata, chiavi esterne in elenco.
Utente(*email, username, password, subscription_date) UNIQUE(username)
Segue(*follower, *followed) FK follower -> Utente(email); FK followed -> Utente(email)
Post(*id, testo, data_ora, utente, visibilita) FK utente -> Utente(email)
Commento(*id, testo, data_ora, commento_origine?, post, utente)
FK commento_origine -> Commento(id); FK post -> Post(id); FK utente -> Utente(email)Perché così:
- Segue: molti-a-molti → relazione con le due chiavi, chiave primaria entrambe, due chiavi esterne verso la stessa tabella (colonne con nomi diversi per i due ruoli).
- Pubblica: uno-a-molti con partecipazione obbligatoria di Post (1,1) → fusione in Post, con Utente come chiave esterna non NULL e Data_Ora come attributo di Post.
- Scrive: ternaria con Commento (1,1) → fusione in Commento: chiavi esterne verso Utente e Post (entrambe NOT NULL) e Data_Ora.
- Risponde: ricorsiva uno-a-molti: la chiave esterna sta dal lato max 1, cioè Commento_Risposta: la riga di un commento contiene il suo commento di origine. Partecipazione opzionale (0,1), quindi
commento_originepuò essere NULL (commento di primo livello). Alternativa: tabella a parte Risponde(risposta, origine); non conviene, perché molti commenti non rispondono ad altri ma in generale i NULL non sono sistematici.
Versione SQL (provata in SQLite; in PostgreSQL id sarebbe serial e visibilita un tipo enumerato):
CREATE TABLE Utente (
email TEXT PRIMARY KEY, username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL, subscription_date DATE NOT NULL);
CREATE TABLE Segue (
follower TEXT NOT NULL REFERENCES Utente(email) ON UPDATE CASCADE ON DELETE CASCADE,
followed TEXT NOT NULL REFERENCES Utente(email) ON UPDATE CASCADE ON DELETE CASCADE,
PRIMARY KEY (follower, followed), CHECK (follower <> followed));
CREATE TABLE Post (
id INTEGER PRIMARY KEY, testo TEXT NOT NULL, data_ora TIMESTAMP NOT NULL,
utente TEXT NOT NULL REFERENCES Utente(email) ON DELETE CASCADE,
visibilita TEXT NOT NULL DEFAULT 'public' CHECK (visibilita IN ('public','private','friends')));
CREATE TABLE Commento (
id INTEGER PRIMARY KEY, testo TEXT NOT NULL, data_ora TIMESTAMP NOT NULL,
commento_origine INTEGER REFERENCES Commento(id) ON DELETE CASCADE,
post INTEGER NOT NULL REFERENCES Post(id) ON DELETE CASCADE,
utente TEXT NOT NULL REFERENCES Utente(email) ON DELETE CASCADE);Il vincolo 1 è un CHECK; il vincolo 5 un CHECK ... IN; il 4 un UNIQUE; i vincoli 2 e 3 coinvolgono più tabelle e non sono esprimibili con un CHECK: servono trigger o controllo applicativo. Una query che trova le violazioni del vincolo 2:
SELECT r.id FROM Commento r JOIN Commento o ON r.commento_origine = o.id
WHERE r.post <> o.post;Con i dati del laboratorio (5 utenti, 5 post, 6 commenti di cui 3 risposte) restituisce zero righe: il vincolo è rispettato.
ON DELETE CASCADE. Come nel laboratorio, cancellare un utente cancella i suoi post, commenti e legami di follow; cancellare un post cancella i suoi commenti; cancellare un commento cancella le sue risposte.
5. Osservazioni sul materiale del corso
- Nel diagramma ER del laboratorio le relazioni Segue e Pubblica sono entrambe etichettate SCEGLIE, ma in uno schema i nomi delle relazioni devono essere univoci: è un errore di etichetta (nello schema relazionale e nelle query si usano Segue e il campo
utentedi Post). - Il laboratorio aggiunge allo schema un vincolo di unicità sullo username e il controllo che nessuno segua se stesso, che non compaiono nell'ER del tema e vanno dunque dichiarati tra i vincoli esterni.
Domande d'esame
Perché Risponde ha cardinalità (0,N) lato origine e (0,1) lato risposta? Traccia. Un commento può ricevere molte risposte ma risponde al più a un altro commento (albero). Con (1,1) sul lato risposta nessun commento di primo livello potrebbe esistere.
Come si garantisce che una risposta appartenga allo stesso post dell'origine? Traccia. Non è esprimibile con il diagramma né con un CHECK a tabella singola: vincolo esterno, realizzato con trigger o controllo applicativo; una query di verifica cerca le coppie con post diversi.
Versione ripasso
- Requisiti: Utente (email, password, username, data iscrizione), Post (testo, visibilità, data e ora, autore), Commento (testo, data e ora, autore, post, origine). Teoria: Relazioni ricorsive, cardinalità e vincoli di integrità nel modello ERI vincoli di integrità di uno schema ER sono di quattro tipi: di cardinalità sulle relazioni, di cardinalità sugli attributi, di identificazione sulle entità e vincoli esterni. La cardinalità (min,max) di un'entità e con ruolo u in una relazione r dice a quante istanze di r partecipa ogni istanza di e: min 0 = partecipazione opzionale, min 1 = obbligatoria, max 1 = al più una volta, max N = molte; le relazioni binarie si classificano per i massimi in uno-a-uno, uno-a-molti, molti-a-molti. I vincoli di cardinalità non permettono di violare la semantica estensionale (una coppia compare una volta sola). Una relazione ricorsiva collega un'entità con se stessa e richiede i ruoli (Predecessore e Successore, Sorgente e Destinazione): con le cardinalità si ottengono catene, alberi e grafi diretti; grafi non diretti, assenza di cicli e di cappi richiedono vincoli esterni; i multigrafi si modellano con una terza entità (etichetta, colore). Gli attributi hanno cardinalità (1,1) di default, (0,1) se opzionali, (x,N) se multivalore.Relazioni ricorsive, cardinalità e vincoli di integrità nel modello ER →.
- Scelte: Segue = relazione ricorsiva molti-a-molti (ruoli Follower e Followed); ogni commento appartiene a un post e può rispondere a un altro commento.
- ER: Pubblica Utente (0,N) - Post (1,1) con Data_Ora; Scrive Utente (0,N), Post (0,N), Commento (1,1) con Data_Ora; Risponde Commento_Origine (0,N) - Commento_Risposta (0,1) (albero); Segue (0,N)-(0,N).
- Vincoli esterni: non seguire se stessi; risposta sullo stesso post dell'origine; data commento non anteriore; username unico; visibilità tra public, private, friends.
- Relazionale: Utente(*email, username, password, subscription_date); Segue(*follower, *followed); Post(*id, testo, data_ora, utente, visibilita); Commento(*id, testo, data_ora, commento_origine NULL, post, utente). Pubblica e Scrive sono fuse (lato max 1, NOT NULL); Risponde è FK nullable nel lato risposta; Segue è N:N con due FK sulla stessa tabella.
- SQL: CHECK per follower diverso da followed e per le visibilità, UNIQUE sullo username,
ON DELETE CASCADE; i vincoli su più tabelle richiedono trigger. - Errori tipici: Risponde con (1,1); dimenticare i ruoli di Segue; FK dal lato sbagliato; il corso chiama SCEGLIE due relazioni diverse (errore di etichetta).
- Collegamenti: Ristrutturazione dello schema ER e traduzione nel modello relazionaleLa progettazione logica ha due passi. 1) Ristrutturazione dello schema ER, per togliere i costrutti che il modello relazionale non esprime: analisi delle ridondanze (attributi derivati e cicli di relazioni, decisa con volume dei dati e carico, tabelle di frequenza e accessi), eliminazione degli attributi multivalore (nuova entità), composti (appiattiti o nuova entità), delle IS-A (relazione con partecipazione (1,1) dalla sottoclasse) e delle generalizzazioni (opzione 1 relazioni, 2 accorpamento nel padre con attributo discriminante, 3 accorpamento nei figli, solo se completa e disgiunta), scelta degli identificatori principali (niente cicli di identificazione esterna), riscrittura dei vincoli esterni, partizionamento e accorpamento di entità. 2) Traduzione quasi automatica nel modello relazionale: ogni entità diventa una relazione con la chiave primaria data dall'identificatore principale (anche esterno); una relazione molti-a-molti diventa una relazione con le chiavi delle entità; una uno-a-molti con partecipazione obbligatoria si fonde con l'entità dal lato max 1 con una chiave esterna; con partecipazione opzionale si fonde (NULL) o si crea una relazione a parte; le uno-a-uno si fondono sul lato con partecipazione obbligatoria; le ternarie seguono la stessa logica con le chiavi di tutte le entità.Ristrutturazione dello schema ER e traduzione nel modello relazionale →, Modello relazionale - relazioni, chiavi e vincoliIl modello relazionale (Codd, IBM, 1970) rappresenta i dati con relazioni, cioè tabelle, ed è basato su valori: i legami tra relazioni sono confronti di valori, non puntatori, il che garantisce indipendenza dalle strutture fisiche, portabilità e bidirezionalità. Una relazione matematica è un sottoinsieme del prodotto cartesiano di n domini (insieme di n-uple ordinate, senza duplicati né ordine tra le righe); una relazione del modello è un insieme di tuple, funzioni dagli attributi ai valori del dominio, quindi non posizionale. Si distinguono schema di relazione e istanza, schema di base di dati (relazioni più vincoli) e istanza. NULL è un valore speciale fuori da ogni dominio. I vincoli di integrità sono intra-relazionali (di dominio, di tupla, di chiave) e inter-relazionali (integrità referenziale, con la chiave esterna). Superchiave: insieme di attributi che non ripete mai i valori; chiave: superchiave minimale; ogni relazione ne ha almeno una (tutti gli attributi); la chiave primaria è una chiave scelta, senza NULL.Modello relazionale - relazioni, chiavi e vincoli →. Schema relazionale e SQL essenziale.
Utente(*email, username UNIQUE, password, subscription_date)
Segue(*follower, *followed) CHECK follower <> followed
Post(*id, testo, data_ora, utente, visibilita)
Commento(*id, testo, data_ora, commento_origine?, post, utente)- Dati del laboratorio: 5 utenti, 5 post, 6 commenti (3 risposte), 6 legami di follow; la query di verifica dello stesso post tra risposta e origine dà zero righe; un self-follow è rifiutato dal CHECK; cancellare un utente con
ON DELETE CASCADEtoglie post, commenti e follow. - Cardinalità: Risponde (0,N) origine e (0,1) risposta (albero); Scrive ternaria con Commento (1,1); Pubblica Post (1,1).
- Non esprimibili con CHECK: risposta sullo stesso post dell'origine, data del commento successiva al post: trigger o applicazione.