Dubbio esercitazione database

Stato
Discussione chiusa ad ulteriori risposte.

krame

Utente Silver
18 Gennaio 2010
138
25
1
94
Salve, per esercitarmi nella creazione di database mi sto esercitando utilizzando un libro, però non avendo modo di confrontare in alcun posto la soluzione e essendomi sorti dei quesiti, sto facendo un post nella speranza che qualcuno sappia darmi delle rispose.

La traccia dell'esercizio è la seguente:
upload_2017-2-16_18-9-11.png


Dopo aver letto la traccia sono giunto al seguente schema E/R:
upload_2017-2-16_19-19-41.png

Ho messo degli attributi giusto per rendere l'idea, ovviamente può essere migliorato sia in studenti che docenti , evitando la ripetizione di attributi quali nome e cognome e/o informazioni fiscali, però giusto per rendere l'idea ho omesso questa miglioria perché voglio capire se ho raggiunto l'obiettivo posto dalla traccia.

Quindi otterrò se seguenti tabelle:
Studenti(Matricola(PK), Nome, Cognome, Classe, Sezione)
Recuperi(Matricola(FK,PK), ID_Materia(FK,PK), Voto, Data_Voto)
Materie(ID(PK), Denominazione)
Docenti(C_Fiscale(PK), Nome, Cognome, ID_Materia(FK))

Innanzitutto vorrei capire se effettivamente il diagramma è corretto e com'è possibile, se c'è un metodo, per verificare la validità di un database.
Anche perché i miei dubbi sono sorti nelle richieste successive, soprattutto per una query proposta di seguito:
upload_2017-2-16_19-25-27.png


Nella traccia questo punto non è richiesto, ovvero la possibilità di risalire al docente che insegna nel corso di recupero.
Quindi avevo pensato a due possibili soluzioni:
1)Aggiungere Docenti.C_Fiscale come chiave esterna nella tabella Recuperi, creando una relazione ternaria
2)Semplificare il database, mi spiego meglio:
Essendo che un docente insegna una sola materia, possiamo trasformare la tabella recuperi nel seguente modo "Recuperi(Matricola(PK)(FK), C_Fiscale(PK)(FK), Voto, Data_Voto)". Perché così facendo sappiamo il docente che insegna nel corso di recupero e in modo univoco possiamo sapere la materia del corso, essendo che il docente insegna una sola materia.

Il libro in vari punti crea confusione, che spesso ho sfatato grazie ad internet, ma questa volta sto dubitando della soluzione da me trovata, perché comunque stravolgerebbe la traccia stessa dell'esercizio.

Qualcuno sa come aiutarmi o ha qualche consiglio da darmi?
Grazie in anticipo
 
Potresti fare delle prove pratiche, per fare questo puoi usare phpmyadmin (lo trovi su XAMPP oppure anche su altervista) comunque le associazioni n a n non sono mai una buona cosa, nel diagramma c'è: Studenti >--< Materia puoi sostituirlo inserendo nel mezzo una terza entità
 
Potresti fare delle prove pratiche, per fare questo puoi usare phpmyadmin (lo trovi su XAMPP oppure anche su altervista) comunque le associazioni n a n non sono mai una buona cosa, nel diagramma c'è: Studenti >--< Materia puoi sostituirlo inserendo nel mezzo una terza entità
Si, infatti nella parte sottostante allo schema E/R , tra le varie tabelle, ho creato quella "Recuperi" che per l'appunto è l'entità che si ottiene dall'associazione N a N.
Le prove le effettuo spesso con XAMPP, però se il database è sbagliato da un punto di vista logico e della comprensione del testo relativo alla traccia, non ho modo di verificarlo del tutto.
Ritieni che nel complesso sia tutto corretto o il database andava ideato diversamente?
 
Quindi otterrò se seguenti tabelle:
Studenti(Matricola(PK), Nome, Cognome, Classe, Sezione)
Recuperi(Matricola(FK,PK), ID_Materia(FK,PK), Voto, Data_Voto)
Materie(ID(PK), Denominazione)
Docenti(C_Fiscale(PK), Nome, Cognome, ID_Materia(FK))
Elenco dei docenti di uno studente conoscendone il codice
Per avere l'elenco dei docenti dovrai andare a fare una select mettendo in relazione la tabella Recuperi con la tabella Docenti. La clausola where ti viene già indicata, ovvero il codice della matricola dello studente.
Se non riesci subito a scrivere la query ti consiglio di spezzare il ragionamento in query più semplici....
1) Inizia a recuperare tutti i recuperi che uno specifico studente deve fare
2) Questo elenco, come potrai vedere, contiene il riferimento alla materia che, guarda caso ;), lo hai inserito anche nella tabella docenti
3) Ora metti in relazione le due cose

Nella traccia questo punto non è richiesto, ovvero la possibilità di risalire al docente che insegna nel corso di recupero.
Quindi avevo pensato a due possibili soluzioni:
1)Aggiungere Docenti.C_Fiscale come chiave esterna nella tabella Recuperi, creando una relazione ternaria
Non serve aggiungere la chiave del docente anche nella tabella dei Recuperi. Puoi risalire facilmente al docente che insegna quel determinato recupero grazie alla chiave ID_Materia (come spiegato prima)

2)Semplificare il database, mi spiego meglio:
Essendo che un docente insegna una sola materia, possiamo trasformare la tabella recuperi nel seguente modo "Recuperi(Matricola(PK)(FK), C_Fiscale(PK)(FK), Voto, Data_Voto)". Perché così facendo sappiamo il docente che insegna nel corso di recupero e in modo univoco possiamo sapere la materia del corso, essendo che il docente insegna una sola materia.
A dire il vero, così, ti sei proprio perso la relazione tra lo studente e il corso di recupero, in quanto la relazione "Recuperi" è qualcosa che nasce tra lo studente e la materia. I docenti non hanno relazioni con gli studenti. Anche nella vita reale, tu frequenti una Materia e il tuo Docente insegna una Materia, ma questo non vuol dire che tu stai frequentando un Docente.
 
Per avere l'elenco dei docenti dovrai andare a fare una select mettendo in relazione la tabella Recuperi con la tabella Docenti. La clausola where ti viene già indicata, ovvero il codice della matricola dello studente.
Se non riesci subito a scrivere la query ti consiglio di spezzare il ragionamento in query più semplici....
1) Inizia a recuperare tutti i recuperi che uno specifico studente deve fare
2) Questo elenco, come potrai vedere, contiene il riferimento alla materia che, guarda caso ;), lo hai inserito anche nella tabella docenti
3) Ora metti in relazione le due cose


Non serve aggiungere la chiave del docente anche nella tabella dei Recuperi. Puoi risalire facilmente al docente che insegna quel determinato recupero grazie alla chiave ID_Materia (come spiegato prima)


A dire il vero, così, ti sei proprio perso la relazione tra lo studente e il corso di recupero, in quanto la relazione "Recuperi" è qualcosa che nasce tra lo studente e la materia. I docenti non hanno relazioni con gli studenti. Anche nella vita reale, tu frequenti una Materia e il tuo Docente insegna una Materia, ma questo non vuol dire che tu stai frequentando un Docente.

Si infatti il secondo punto era molto vago e sono ben cosciente della perdita completa della relazione base.

Le query le so svolgere, ma il problema deriva proprio da un concetto logico. Io tramite recuperi, che contiene l'ID della materia, posso risalire alla materia insegnata in quel corso, ma essendo che la relazione tra materia è docenti è del tipo uno a molti, non avrò modo di sapere quali di quei molti docenti insegnano nel corso.
Per capirci meglio, posso avere la materia "Italiano" essa è insegnata da uno o più docenti perché appunto è di tipo a molti. In compenso però un docente insegna una sola materia.
Se io svolgo la query del tipo:

Codice:
SELECT Docenti.*
FROM Recuperi, Docenti, Materie
WHERE Recuperi.ID_Materia = Materie.ID_Materia
AND Materie.ID_Materia = Docenti.ID_Materia
AND Recuperi.Matricola = 1;

In risultato si otterrò i docenti relativi allo studente,indicato tramite la matricola, ma non solo un docente ma tutti i possibili docenti che insegnano la materia "italiano".
E' questo dubbio che mi ha portato a pensare che lo schema e/r sia incompleto o sbagliato, oppure che la traccia stessa lo sia.
Come risolveresti la query facendo evidenziare solo il docente che insegna nel corso di recupero e non tutti i docenti che insegnano la materia correlata alla Matricola inserita?
Grazie e scusami per il disturbo , ma ci sto sbattendo la testa da giorni ahhaha
 
Io lo interpreterei proprio diversamente :D
schema.png

Dove le principali tabelle sono:
  • ANA_STUDENTI: anagrafica degli studenti;
  • ANA_MATERIA: anagrafica delle materie erogate nelle scuola;
  • ANA_DOCENTI: anagrafica dei docenti, con attenzione alla chiave esterna COD_MATERIA, perchè nel testo viene indicato che un docente insegna una sola materia.
Le altre tabelle che trovi sono:
  • ANA_CLASSE: tutti gli studenti faranno parte di una classe....
  • ANA_ESAMI: nel testo non viene esplicitamente indicato, ma è logico aspettarsi un'anagrafica degli esami erogati...ma chi li eroga? Li erogano i docenti (chiave esterna COD_DOCENTE) per una data specifica.
  • ESAMI: a questo punto gli studenti dovranno fare degli esami e verranno valutati con un voto.
    • La chiave preferisco farla in formato varchar perchè può essere una chiave derivata dalla concatenazione del COD_STUDENTE \ COD_ESAME, in quanto per un esame, lo studente sarà sempre diverso, e questo non porta a chiavi duplicate.
  • ANA_RECUPERO: allo stesso modo degli esami, sono i docenti ad erogare dei corsi di recupero, magari inserendo una data di inizio e una di fine;
  • ESAMI_RECUPERO: questa tabella contiene gli esiti degli esami di recupero in una specifica data.
    • in questo caso, la chiave può essere concatenata da COD_STUDENTE \ COD_RECUPERO \ DATA (data in formato es: 20170218)
  • CLASSE_DOCENTE: ogni docente potrà avere più classi in cui insegnare....

Ora ti spiego perchè sono state aggiunte queste tabelle in più:
  • La tabella ESAMI ti servirà per vedere quali studenti vanno mala in una materia così che il docente potrà erogare successivamente un corso di recupero.
  • La tabella della CLASSE l'ho inserita per rispondere direttamente alla domanda del testo che, a parer mio, non è del tutto chiara.
Tornando alla domanda dell'esercizio:
Elenco dei docenti di uno studente conoscendone il codice
Non viene indicato se vuole sapere i docenti dei soli alunni che devono fare un corso di recupero o, in generale, di un qualsiasi studente, anche se non sta facendo il corso di recupero...Ed è per questo che ho dovuto aggiungere la tabella specifica.
SQL:
SELECT ANA_DOCENTI.*
FROM ANA_DOCENTI JOIN CLASSE_DOCENTI ON ANA_DOCENTI.COD_DOCENTE = CLASSE_DOCENTI.COD_DOCENTE
   JOIN ANA_CLASSE ON CLASSE_DOCENTI.COD_CLASSE = ANA_CLASSE.COD_CLASSE
   JOIN ANA_STUDENTI ON ANA_CLASSE.COD_CLASSE = ANA_STUDENTI.COD_CLASSE
WHERE ANA_STUDENTI.COD_STUDENTE = 'A001'

Se invece vuoi sapere solo i docenti di uno studente che sta frequentando un corso di recupero:
SQL:
SELECT ANA_DOCENTI.*
FROM ANA_DOCENTI JOIN ANA_RECUPERO ON ANA_DOCENTI.COD_DOCENTE = ANA_RECUPERO.COD_DOCENTE
   JOIN ESAMI_RECUPERO ON ANA_RECUPERO.COD_RECUPERO = ESAMI_RECUPERO.COD_RECUPERO
WHERE ESAMI_RECUPERO.COD_STUDENTE = 'A001'
Anche se, forse te ne sei già accorto, lo schema dovrebbe prevedere una tabella FREQUENZA_RECUPERO dove si indicheranno tutti gli studenti che frequentano quel determinato corso di recupero, altrimenti, dal mio schema, non potrai sapere a priori quali studenti stanno frequentando un corso fino al momento dell'esame intermedio.


Mentre per rispondere a questa domanda:
la possibilità di risalire al docente che insegna nel corso di recupero.
SQL:
SELECT ANA_DOCENTI.*
FROM ANA_DOCENTI JOIN ANA_RECUPERO ON ANA_DOCENTI.COD_DOCENTE = ANA_RECUPERO.COD_DOCENTE
 
Io lo interpreterei proprio diversamente :D

Dove le principali tabelle sono:
  • ANA_STUDENTI: anagrafica degli studenti;
  • ANA_MATERIA: anagrafica delle materie erogate nelle scuola;
  • ANA_DOCENTI: anagrafica dei docenti, con attenzione alla chiave esterna COD_MATERIA, perchè nel testo viene indicato che un docente insegna una sola materia.
Le altre tabelle che trovi sono:
  • ANA_CLASSE: tutti gli studenti faranno parte di una classe....
  • ANA_ESAMI: nel testo non viene esplicitamente indicato, ma è logico aspettarsi un'anagrafica degli esami erogati...ma chi li eroga? Li erogano i docenti (chiave esterna COD_DOCENTE) per una data specifica.
  • ESAMI: a questo punto gli studenti dovranno fare degli esami e verranno valutati con un voto.
    • La chiave preferisco farla in formato varchar perchè può essere una chiave derivata dalla concatenazione del COD_STUDENTE \ COD_ESAME, in quanto per un esame, lo studente sarà sempre diverso, e questo non porta a chiavi duplicate.
  • ANA_RECUPERO: allo stesso modo degli esami, sono i docenti ad erogare dei corsi di recupero, magari inserendo una data di inizio e una di fine;
  • ESAMI_RECUPERO: questa tabella contiene gli esiti degli esami di recupero in una specifica data.
    • in questo caso, la chiave può essere concatenata da COD_STUDENTE \ COD_RECUPERO \ DATA (data in formato es: 20170218)
  • CLASSE_DOCENTE: ogni docente potrà avere più classi in cui insegnare....

Ora ti spiego perchè sono state aggiunte queste tabelle in più:
  • La tabella ESAMI ti servirà per vedere quali studenti vanno mala in una materia così che il docente potrà erogare successivamente un corso di recupero.
  • La tabella della CLASSE l'ho inserita per rispondere direttamente alla domanda del testo che, a parer mio, non è del tutto chiara.
Tornando alla domanda dell'esercizio:

Non viene indicato se vuole sapere i docenti dei soli alunni che devono fare un corso di recupero o, in generale, di un qualsiasi studente, anche se non sta facendo il corso di recupero...Ed è per questo che ho dovuto aggiungere la tabella specifica.
SQL:
SELECT ANA_DOCENTI.*
FROM ANA_DOCENTI JOIN CLASSE_DOCENTI ON ANA_DOCENTI.COD_DOCENTE = CLASSE_DOCENTI.COD_DOCENTE
   JOIN ANA_CLASSE ON CLASSE_DOCENTI.COD_CLASSE = ANA_CLASSE.COD_CLASSE
   JOIN ANA_STUDENTI ON ANA_CLASSE.COD_CLASSE = ANA_STUDENTI.COD_CLASSE
WHERE ANA_STUDENTI.COD_STUDENTE = 'A001'

Se invece vuoi sapere solo i docenti di uno studente che sta frequentando un corso di recupero:
SQL:
SELECT ANA_DOCENTI.*
FROM ANA_DOCENTI JOIN ANA_RECUPERO ON ANA_DOCENTI.COD_DOCENTE = ANA_RECUPERO.COD_DOCENTE
   JOIN ESAMI_RECUPERO ON ANA_RECUPERO.COD_RECUPERO = ESAMI_RECUPERO.COD_RECUPERO
WHERE ESAMI_RECUPERO.COD_STUDENTE = 'A001'
Anche se, forse te ne sei già accorto, lo schema dovrebbe prevedere una tabella FREQUENZA_RECUPERO dove si indicheranno tutti gli studenti che frequentano quel determinato corso di recupero, altrimenti, dal mio schema, non potrai sapere a priori quali studenti stanno frequentando un corso fino al momento dell'esame intermedio.


Mentre per rispondere a questa domanda:

SQL:
SELECT ANA_DOCENTI.*
FROM ANA_DOCENTI JOIN ANA_RECUPERO ON ANA_DOCENTI.COD_DOCENTE = ANA_RECUPERO.COD_DOCENTE
Allora era necessario migliorare il database, perché in quel modo mancavano elementi determinanti. Ma come dicevi tu stesso prima, separando in quel modo materia e studente non si va perdendo la relazione definita nella traccia? o la relazione rimane ma in modo indiretto ?
 
Allora era necessario migliorare il database, perché in quel modo mancavano elementi determinanti. Ma come dicevi tu stesso prima, separando in quel modo materia e studente non si va perdendo la relazione definita nella traccia? o la relazione rimane ma in modo indiretto ?
Dal mio schema, tralasciando le tabelle ESAMI e quelle per le CLASSI, con la tua idea ci sei andato molto vicino, ovvero:
"Recuperi(Matricola(PK)(FK), C_Fiscale(PK)(FK), Voto, Data_Voto)".
Il problema è che, per come hai definito nello schema "Recuperi" diventava sbagliato....

In ogni caso, secondo me, non c'è una soluzione unica...probabilmente qualcun'altro lo farà in modo diverso!
 
Dal mio schema, tralasciando le tabelle ESAMI e quelle per le CLASSI, con la tua idea ci sei andato molto vicino, ovvero:

Il problema è che, per come hai definito nello schema "Recuperi" diventava sbagliato....

In ogni caso, secondo me, non c'è una soluzione unica...probabilmente qualcun'altro lo farà in modo diverso!
Capito, ti ringrazio per le risposte e la pazienza , mi sei stato d'aiuto :D
 
Stato
Discussione chiusa ad ulteriori risposte.