Passa al contenuto principale

Capitolo 02

Generalizzazioni

All animals are equal, but some animals are more equal than others.

George Orwell, La fattoria degli animali (1945)

Nella lezione precedente studenti e professori erano due entità separate, ognuna con il suo nome e il suo identificatore. Le due entità hanno però molto in comune: nome e cognome, una bacchetta, un Patronus. Ogni volta che il dominio chiede qualcosa di nuovo su tutte le persone di Hogwarts, il modello deve scriverlo due volte, una per entità. In questa lezione raccogliamo ciò che studenti e professori hanno in comune in un’entità più generale, e vediamo che questa raccolta, comoda nel diagramma, si può trasformare in tabelle in tre modi, nessuno dei quali conserva tutto.

Due entità con le stesse proprietà​

Immaginiamo che il database di Hogwarts debba registrare le bacchette di tutti, studenti e professori: anche Piton ha una bacchetta, come Harry. Con il modello che abbiamo servono due associazioni possiede, una fra studente e bacchetta e una fra professore e bacchetta, con le stesse cardinalità. Lo stesso vale per nome e cognome, che compaiono fra gli attributi di tutte e due le entità, e per il Patronus della lezione “Entità e attributi”, che hanno anche i professori: quello di Piton è una cerva.

Studenti e professori sono due casi particolari della stessa cosa, una persona che vive a Hogwarts. Il modello E/R lo esprime con una generalizzazione: un’entità persona, con gli attributi e le associazioni che tutte le persone hanno, e sotto di lei le entità studente e professore, ognuna con ciò che riguarda solo lei: l’anno per lo studente, la materia per il professore.

Se hai già scritto classi in Python, la generalizzazione ti ricorda l’ereditarietà fra classi, e il parallelo regge: la figlia ha tutto ciò che ha il padre, più qualcosa di suo. Come per entità e classi, nel modello E/R mancano i metodi.

La persona generalizza lo studente e il professoreL'entità persona, con il codice come identificatore, nome e cognome, è collegata all'entità bacchetta dall'associazione possiede: (0,N) accanto a persona, (1,1) accanto a bacchetta. Sotto la persona, una generalizzazione parziale ed esclusiva (p,e) ha due entità figlie: studente, con l'attributo anno, e professore, con l'attributo materia.bacchettalegnonucleolunghezzapersonacodicenomecognomestudenteannoprofessoremateriapossiede(0,N)(1,1)(p,e)

Nel diagramma la generalizzazione è una freccia che va dalle entità figlie al padre. Accanto a persona, in possiede, il minimo è 0: a Hagrid la bacchetta l’hanno spezzata quando è stato espulso, e da allora la sua magia passa da un ombrello rosa. Gli attributi di studente e professore sono soltanto quelli propri: il nome, il codice e la bacchetta di uno studente stanno nel padre, e valgono per lui come per ogni altra persona.

La copertura​

Accanto alla freccia il diagramma porta due lettere, (p,e). Sono la copertura della generalizzazione, e rispondono a due domande sul dominio, come le cardinalità.

La prima domanda: ogni persona registrata è per forza uno studente o un professore? Hagrid no. Nei primi due anni di Harry a Hogwarts è il guardiacaccia della scuola, e non è né uno studente né un professore. Se il database registra anche Hagrid, alcune persone non appartengono a nessuna entità figlia, e la generalizzazione è parziale, p. Se ogni persona registrata è per forza uno studente o un professore, è totale, t.

La seconda domanda: una persona può essere studente e professore insieme? Fra gli studenti e i professori di un anno scolastico, no: la generalizzazione è esclusiva, e. Immaginiamo però l’archivio della lezione sulle chiavi, con tutti gli studenti passati da Hogwarts. Piton e Lupin a Hogwarts hanno studiato, e anni dopo insegnato, senza essersi mai resi simpatici né agli studenti né ai professori: nell’archivio Piton è un’occorrenza di studente e anche di professore, e la generalizzazione è sovrapposta, o, dall’inglese overlapping.

La copertura: (p,e) in un anno, (p,o) nell’archivioDentro l’insieme persona stanno gli insiemi studente e professore. In un anno scolastico sono separati: Harry è studente, Piton professore, Hagrid e Gazza fuori da tutti e due; la copertura è (p,e). Nell’archivio di tutti gli anni i due insiemi si sovrappongono, e Piton e Hagrid stanno in tutti e due; Gazza resta fuori, e la copertura è (p,o).personastudenteprofessoreHarryPitonHagridGazza(p,e)(p,o)
La copertura: (p,e) in un anno, (p,o) nell’archivioDentro l’insieme persona stanno gli insiemi studente e professore. In un anno scolastico sono separati: Harry è studente, Piton professore, Hagrid e Gazza fuori da tutti e due; la copertura è (p,e). Nell’archivio di tutti gli anni i due insiemi si sovrappongono, e Piton e Hagrid stanno in tutti e due; Gazza resta fuori, e la copertura è (p,o).personastudenteprofessoreHarryPitonHagridGazza(p,e)(p,o)

Nell’archivio di tutti gli anni Piton e Hagrid sono stati studenti e poi professori: gli insiemi si sovrappongono.

  1. In un anno scolastico nessuno è studente e professore insieme, e Hagrid non è nessuno dei due.
  2. Nell’archivio di tutti gli anni Piton e Hagrid sono stati studenti e poi professori: gli insiemi si sovrappongono.

La copertura, come le cardinalità, non si ricava dai nomi delle entità. Le persone di Hogwarts sono le stesse, ma il database di un anno scolastico ha la copertura (p,e), e l’archivio di tutti gli anni (p,o). Nell’archivio anche Hagrid smette di essere un caso a parte: prima di diventare guardiacaccia è stato studente, fino all’espulsione al terzo anno, e dal terzo anno di Harry è anche professore, con un libro di testo che morde (al contrario di Python Doesn’t Byte).

Tre modi di farne tabelle​

Le tabelle non hanno generalizzazioni: una tabella non ha figlie. Prima di trasformare il modello in tabelle, quindi, ogni generalizzazione va tolta, e i modi di toglierla sono tre. Le regole complete per passare dal modello alle tabelle arrivano nel capitolo 3; qui guardiamo soltanto che cosa perde ciascuno dei tre modi, sulle persone di Hogwarts.

Solo il padre​

Le figlie spariscono dentro il padre. La tabella persona riceve le colonne di tutte le figlie, più una colonna tipo che dice a quale figlia appartiene ogni riga.

codicenomecognometipoannomateria
1HarryPotterstudente1
2SeverusPitonprofessorePozioni
3RubeusHagrid

Hagrid ci sta, con il tipo vuoto, e l’associazione possiede resta una sola. Si perdono però le regole delle figlie: niente impedisce una riga di tipo studente con una materia, o uno studente senza anno. E un’associazione che riguarda solo gli studenti, come appartiene, diventa un’associazione di tutte le persone, professori compresi. Con la copertura sovrapposta, poi, una colonna tipo con un valore solo non sa dire che Piton è stato studente ed è professore.

Solo le figlie​

Il padre sparisce, e ogni figlia riceve i suoi attributi: la tabella studente ha codice, nome, cognome e anno, la tabella professore codice, nome, cognome e materia.

codicenomecognomeanno
1HarryPotter1
codicenomecognomemateria
2SeverusPitonPozioni

Le regole delle figlie restano: uno studente ha un anno e non ha una materia. Si perde invece la persona. Hagrid, che non è né studente né professore, non ha una tabella in cui stare: una copertura parziale con questo modo non si può registrare. Nell’archivio, Piton compare in tutte e due le tabelle, con nome e cognome scritti due volte, ed è la ridondanza del capitolo 1. E l’associazione possiede va raddoppiata, una per tabella.

Padre e figlie, collegati​

Restano tutte e tre le entità. La tabella persona ha codice, nome e cognome; la tabella studente ha il codice e l’anno, la tabella professore il codice e la materia, e il codice di ogni riga di una figlia indica una riga di persona.

codicenomecognome
1HarryPotter
2SeverusPiton
3RubeusHagrid
codiceanno
11
codicemateria
2Pozioni

Hagrid sta nella tabella persona e in nessuna figlia, Piton nell’archivio avrebbe una riga in persona e una in ciascuna figlia, e nome e cognome sono scritti una volta sola. Il prezzo sono gli incroci: per avere il nome e l’anno di uno studente servono due tabelle, unite come il DBMS unisce assegnazione e studente. E neanche questo modo fa rispettare la copertura: in una generalizzazione esclusiva, niente impedisce che lo stesso codice compaia in tutte e due le figlie.

ModoConservaPerde
solo il padrele persone senza figlia, un’associazione solale regole delle figlie e la copertura sovrapposta
solo le figliele regole delle figliele persone senza figlia; nome e cognome scritti due volte
padre e figlietutte le informazionila semplicità delle interrogazioni, e il controllo della copertura

Nessuno dei tre modi va bene in ogni caso. Chi progetta sceglie guardando che cosa il dominio non può permettersi di perdere: con Hagrid da registrare, il modo “solo le figlie” è escluso; con tante interrogazioni su studenti e professori insieme, “padre e figlie” costa un incrocio a ogni domanda.

Mettiti alla provaDomanda 1 / 3

Un database registra soltanto gli studenti e i professori dell’anno scolastico in corso, sotto l’entità persona. Che copertura ha la generalizzazione?

Scegli la risposta corretta