Passa al contenuto principale

Capitolo 02

Le associazioni molti a molti

Tous pour un, un pour tous.

Alexandre Dumas, I tre moschettieri (1844)

Nella lezione precedente i corsi di Hogwarts hanno avuto un identificatore, materia e anno, ma nessuno studente. Ora li colleghiamo agli studenti. Nella lezione “Le cardinalità” questa associazione era l’esempio del terzo tipo, molti a molti: ogni studente segue più corsi, e ogni corso ha più studenti. Un’associazione uno a molti, come appartiene, nelle tabelle finisce in una colonna, la casa nella riga dello studente. In questa lezione vediamo che con il massimo N da tutti e due i lati una colonna non basta, che un’associazione molti a molti ha spesso attributi suoi, e che a volte un’associazione non basta proprio.

I corsi in una colonna​

Il primo tentativo è quello che ha funzionato per la casa: una colonna nella tabella studente. La casa di uno studente stava in una cella, perché è una sola. I corsi sono più di uno, e in questa versione della tabella stanno tutti nella stessa cella, separati da virgole. Il blocco qui sotto mostra le prime righe della tabella studente fatta così; per semplicità, ogni studente segue le stesse quattro materie del suo anno.

Il blocco qui sotto chiede quali studenti seguono Pozioni, e si legge così: il nome dalla tabella studente, per le righe in cui (WHERE) la colonna corsi è uguale a Pozioni. Prima di eseguire il blocco, prova a prevedere quanti nomi elenca.

SELECT nome FROM studente WHERE corsi = 'Pozioni';

Il DBMS non ha sbagliato: ha confrontato due testi, e i due testi sono diversi. L’errore sta nella tabella, che contiene quattro coppie dell’associazione in una cella sola. Un’istruzione che cerca una parola dentro un testo esiste; con questa tabella, però, ogni domanda sui corsi diventa un lavoro sul testo, e la stessa istruzione troverebbe Pozioni anche in un corso chiamato “Pozioni avanzate”. Perché in una tabella ogni cella debba contenere un valore solo lo spiega la prima lezione del capitolo 3; qui basta vedere che cosa succede quando una cella ne contiene quattro.

C’è poi una domanda che con la tabella studente non ha risposta, qualunque istruzione si scriva: che voto ha preso Hermione in Pozioni.

Il voto è della coppia​

Il voto di Hermione in Pozioni non è un’informazione su Hermione, perché Hermione ha un voto per ogni corso che segue. Non è nemmeno un’informazione sul corso di Pozioni del primo anno, che ha un voto per ogni studente. Il voto è un’informazione sulla coppia (Hermione Granger, Pozioni del primo anno): esiste perché Hermione segue quel corso, e ce n’è uno per ogni coppia.

Quando un’associazione ha attributi suoi, spesso il nome più naturale è un sostantivo, il nome del fatto registrato: l’iscrizione di uno studente a un corso. Nella lezione “Le associazioni” abbiamo detto che il nome di un’associazione è di solito un verbo; “di solito” lascia spazio a casi come questo. Nel diagramma l’attributo voto esce dal rombo, come gli attributi di un’entità escono dal rettangolo.

Lo studente si iscrive a un corso, con un votoL'entità studente, identificata dalla matricola, è collegata all'entità corso, identificata da materia e anno, dall'associazione iscrizione, che ha l'attributo voto. Accanto a studente la cardinalità è (1,N), accanto a corso (0,N).studentematricolanomecorsomateriaannoiscrizionevoto(1,N)(0,N)

Le cardinalità dicono che ogni studente è iscritto ad almeno un corso, senza un massimo, e che un corso può non avere ancora iscritti. Nelle tabelle un’associazione molti a molti diventa una tabella propria, con una riga per ogni coppia: come si costruisce lo vedremo nel capitolo 3. Il blocco qui sotto ne mostra il risultato, la tabella iscrizione, con una riga per ogni studente e per ogni corso che segue.

Adesso i voti di uno studente si possono chiedere. Il blocco qui sotto elenca materia e voto dalla tabella iscrizione, per le righe in cui lo studente è Neville Longbottom. Chi conosce Neville può prevedere in quale materia ha il voto più alto: prova, prima di eseguire.

SELECT materia, voto FROM iscrizione
WHERE studente = 'Neville Longbottom';

La stessa coppia due volte​

Torniamo al registro dei punti. Ogni assegnazione lega un professore a uno studente e ha un valore, i punti. Ogni professore dà punti a molti studenti, e ogni studente ne riceve da molti professori: l’assegnazione sembra un’associazione molti a molti fra professore e studente, con l’attributo punti, costruita come l’iscrizione con il voto.

Nel file punti.json, che trovi nel pannello “Archivio”, la quarta e la quinta assegnazione sono identiche: Piton toglie un punto a Harry per insolenza, e poi un altro per non aver aiutato Neville, nella prima lezione di Pozioni. Se l’assegnazione fosse un’associazione, la coppia (Piton, Harry Potter) dovrebbe comparire due volte, una per ogni punto tolto. Un’associazione però è un insieme di coppie, e in un insieme ogni elemento c’è una volta sola: la coppia (Piton, Harry Potter) c’è oppure non c’è, e il suo attributo punti ha un valore solo.

La stessa coppia due volte: associazione o entitàNel file punti.json la quarta e la quinta assegnazione sono uguali: Piton, Harry Potter, −1. Come coppie di un’associazione entrano in un insieme, la seconda coincide con la prima e ne resta una sola, con un solo −1. Come occorrenze di un’entità restano due, distinte dall’id 4 e dall’id 5, ognuna con il suo −1.punti.json, quarta e quinta assegnazionePitonHarry Potter−1PitonHarry Potter−1come associazionePitonHarry Potter−1PitonHarry Potter−1una coppia sola, un solo −1come entitàid 4PitonHarry Potter−1id 5PitonHarry Potter−1due occorrenze, una per id
La stessa coppia due volte: associazione o entitàNel file punti.json la quarta e la quinta assegnazione sono uguali: Piton, Harry Potter, −1. Come coppie di un’associazione entrano in un insieme, la seconda coincide con la prima e ne resta una sola, con un solo −1. Come occorrenze di un’entità restano due, distinte dall’id 4 e dall’id 5, ognuna con il suo −1.punti.json, quarta e quinta assegnazionePitonHarry Potter−1PitonHarry Potter−1come associazionePitonHarry Potter−1PitonHarry Potter−1una coppia sola, un solo −1come entitàid 4PitonHarry Potter−1id 5PitonHarry Potter−1due occorrenze, una per id

Come entità, le due assegnazioni restano due occorrenze, con id 4 e id 5.

  1. Nel registro, Piton toglie due volte un punto a Harry: due assegnazioni uguali.
  2. Come associazione, le due coppie (Piton, Harry Potter) sono la stessa: ne resta una, con un solo −1.
  3. Come entità, le due assegnazioni restano due occorrenze, con id 4 e id 5.

Le due scorciatoie che vengono in mente non funzionano. Sommare i due punti in un solo valore, −2, fa perdere un’informazione: i punti tolti sono stati due volte uno, in due momenti diversi. Aggiungere la data come attributo non cambia niente, perché l’occorrenza resta la coppia, e la data sarebbe un attributo di quella coppia, uno solo.

Quando lo stesso fatto può ripetersi per la stessa coppia, il fatto non è un’associazione: è un’entità, con un’occorrenza per ogni volta che succede. L’assegnazione è un’entità con l’attributo punti, e le sue occorrenze si distinguono con un identificatore assegnato apposta, il numero progressivo id della tabella assegnazione. Allo studente e al professore la legano due associazioni uno a molti: ogni assegnazione è ricevuta da uno studente e data da un professore.

L'assegnazione come entità fra lo studente e il professoreTre entità impilate: studente (matricola), assegnazione (id, identificatore, e punti) e professore (nome). L'associazione riceve collega studente, con cardinalità (0,N), e assegnazione, con (1,1). L'associazione dà collega professore, con (0,N), e assegnazione, con (1,1).studentematricolanomeassegnazioneidpuntiprofessorenomemateriaricevedà(0,N)(1,1)(0,N)(1,1)

Il diagramma si legge così: ogni assegnazione è ricevuta da esattamente uno studente e data da esattamente un professore; uno studente può ricevere da zero a N assegnazioni, e un professore può darne da zero a N. Le due assegnazioni di Piton a Harry sono due occorrenze di assegnazione, con due id diversi, e ognuna compare in una coppia di riceve e in una di dà.

Il criterio per scegliere fra associazione ed entità è una domanda sul dominio: la stessa coppia può comparire più di una volta? Uno studente si iscrive a un corso una volta sola, quindi l’iscrizione è un’associazione. Un professore può dare punti allo stesso studente quante volte vuole, quindi l’assegnazione è un’entità.

Mettiti alla provaDomanda 1 / 3

Quale di questi attributi appartiene all’associazione iscrizione fra studente e corso?

Scegli la risposta corretta