PDA

View Full Version : Progetto Database


anonimizzato
14-09-2006, 19:48
Ciao a tutti,

in questi giorni, con molta umiltà, stavo cercando di implementare la struttura di un Database per un sito che amministro da un pò di tempo che per ora è totalmente statico.

Il sito è www.lalocomotivaweb.it

quello che volevo fare era creare un DB che archiviasse le numerose informazioni sui corsi principalmente.

Pur non essendo certo difficile ho notato che dai dati presenti si venivano a creare moltre relazioni M:N (molti a molti)

Ora ho "risolto" in questo modo (nel file allegato).

Volevo sapere, alla luce di quello che potete vedere da sito, se il DB regge oppure ci sono errori macroscopici o mancanze.

Allego anche uno screenshot.

Grazie a tutti coloro che vorranno darmi un aiuto o suggerimento.

Scusate ma è il mio primo progetto.

Cerco di spiegare un pò le tabelle

Corso: identificazione generica dei vari programmi, es:
Corso di inglese di 1° livello (base)
Corso di inglese di 2° livello (medio)
ecc.

CORSI:
Nella quasi totalità dei casi hanno informazioni generiche quale il costo, la durata in mesi, il metodo di insegnamento utilizzato, il luogo di svolgimento (ovvero le aule e non le palestre ad esempio.) e sono comuni per tutti i livelli.

LIVELLI:
Ovvero una delle varie parti del Corso (se inteso come categoria)
In inglese potrebbe essere inteso in base al livello di insegnamento mentre in informatica in base al software studiato, in ginnastica se per adulti o per ragazzi ecc.

PROGRAMMA:
è la mega tabella di collegamento che ho creato per identificare in modo univoco le relazioni:
un programma può essere

ProgrammaID
Corso: INGLESE
Livello: Livello 1
Giorno: martedì
Orario da: 18.00
Orario a: 20.00
Luogo: Aule corsi
Ciclo: dal 07/10/2006 al 04/02/2007



il ciclo è importante per esempio perchè uno stesso identico corso potrebbe essere fatto più avanti ma sempre nello stesso posto allo stesso giorno con gli stessi orari ecc.
in questo modo ho un record PROGRAMMAID "univoco".

CICLI:
Una sorta di periodo di svolgimento, lo hanno solo alcuni corsi, ed immaginatelo come i trimestri i scuola.
Dal DATA al DATA

LIVELLI_INFORMATICA
Lo impostata solo come sotto-tabella dei corsi di informatica che in base al livello studiato cambiano in durata e costi in quanto non esiste un valore univoco di costo e durata come per gli altri corsi questo per evitare di aver nella tabella LIVELLI dei campi quasi sempre vuoti come "numero lezioni", "numero ore", "costo" associate solo ai corsi di informatica.

anonimizzato
15-09-2006, 20:23
uppettino

vetto78
15-09-2006, 22:06
Mi potresti spiegare meglio che tipo di informazioni ti servono?
Il tuo schema secondo me si può semplificare ma vorrei capire cosa ti serve e cosa no...

anonimizzato
16-09-2006, 09:44
Ciao,

quello che mi serve è mostrare sulle pagine del sito tutti i vari programmi disponibili per i corsi presentati sul sito www.lalocomotivaweb.it

Ogni Corso come vedi ha dei dati comuni quali: LUOGO, COSTO, DURATA, METODO, ecc. (anche se non sempre)

e poi una differenziazione per i LIVELLI (se ve ne sono, altrimenti si intende come UNICO) circa: GIORNI, ORARI, CICLO (periodo da/a) ecc.

quello che vorrei fare è avere meno dati ridondati possibili ed una struttura efficiente senza impazzire nel mare di relazione 1:N M:N che presenterebbe.

Quello che non mi serve è qualcosa a livello di UTENTE in quanto non esiste interazione, tipo iscirizioni online ecc. è solo una vetrina dei Corsi proposti.

Ho aperto un thread qua (http://forum.html.it/forum/showthread.php?s=&threadid=1029345)

dove un utente mi dice che il DB non è male, ma credo anch'io si possa fare qualcosa per migliorarlo.

Grazie per la risposta.

cionci
16-09-2006, 10:34
Mi sembra che vada bene...duplicazioni non ne vedo...

Fammi capire la relazioni luogo-programma...
Io metterei una relazione luogo-corso...ma bisogna vedere se è corretta...
Lo stesso corso si può svolgere in più luoghi ? In questo momento stai esprimendo che lo stesso programma si può svolgere in più luoghi...

anonimizzato
16-09-2006, 10:54
Mi sembra che vada bene...duplicazioni non ne vedo...

Fammi capire la relazioni luogo-programma...
Io metterei una relazione luogo-corso...ma bisogna vedere se è corretta...
Lo stesso corso si può svolgere in più luoghi ? In questo momento stai esprimendo che lo stesso programma si può svolgere in più luoghi...

Si esatto si può svolgere in più luoghi :)

guarda il corso di ginnastica ad esempio:http://www.lalocomotivaweb.it/corsi-di-ginnastica.htm

Lo stesso corso può svolgersi in diverse palestre quindi mi sembrava giusto metterlo a livello di PROGRAMMA come si vede.

Quello che hanno in comune e che è condiviso a livello di CORSI è la durata, la frequenza settimanale, il costo, l'insegnate ecc.

GINNASTICA DOLCE e GINNASTICA DI MANTENIMENTO, che hanno quote, diverse, li tratti a tutti gli effetti come corsi diversi ... anche perchè lo sono pur essendo sempre "ginnastica".

cionci
16-09-2006, 11:05
Però allora non capisco la distinzione fra Programma e Corso...

Prendendo come esempio quella pagina sai dirmi come verrebbero composte le tabelle Programma e Corso ?

cionci
16-09-2006, 11:08
ok ok ci sono arrivato...va bene... Io eliminerei la relazione Ciclo... Sei sicuro che siano preventivabili cicli successivi a quello corrente ?

anonimizzato
16-09-2006, 11:13
Però allora non capisco la distinzione fra Programma e Corso...

Prendendo come esempio quella pagina sai dirmi come verrebbero composte le tabelle Programma e Corso ?

è perchè se no dovrei ripetere una marea di informazioni per ogni PROGRAMMA e alla fine mi verrebbe fuori un foglio di excel e non un DB :D

Cmq vedo che l'avevi notato ;)

anonimizzato
16-09-2006, 11:15
ok ok ci sono arrivato...va bene... Io eliminerei la relazione Ciclo... Sei sicuro che siano preventivabili cicli successivi a quello corrente ?

Nei corsi di informatica http://www.lalocomotivaweb.it/corsi-di-informatica.htm

Ci sono ad esempio 4 cicli

1° Ciclo
02 Ottobre 2006
2° Ciclo
27 Novembre 2006
3° Ciclo
05 Febbraio 2007
4° Ciclo
02 Aprile 2007

In questo caso non è specificata la data di fine per ogni ciclo quindi pensavo di fare in modo da renderla facoltativa nell'interfaccia (PHP)

cionci
16-09-2006, 11:20
Ho capito anche ciclo...ok...va bene, ma non mi torno una cosa...
Posto così com'è in luoghi diversi non potresti realizzare cicli diversi...ti torna ? Secondo me cicli dovrebbe avere come FK programma_id e dovrebbe essere una relazione tutta chiave... L'ciclo_id in questo caso è una informazione non necessaria...

cionci
16-09-2006, 11:23
Anche livelli secondo me ha qualche problema... Tutti i livelli del corso costano uguale ?

anonimizzato
16-09-2006, 11:28
Ho capito anche ciclo...ok...va bene, ma non mi torno una cosa...
Posto così com'è in luoghi diversi non potresti realizzare cicli diversi...ti torna ? Secondo me cicli dovrebbe avere come FK programma_id e dovrebbe essere una relazione tutta chiave... L'ciclo_id in questo caso è una informazione non necessaria...

Umh spetta perchè non ho capito bene .. :wtf:

anonimizzato
16-09-2006, 11:30
Anche livelli secondo me ha qualche problema... Tutti i livelli del corso costano uguale ?

No esatto se vedi livelli_informatica vedrai che ho aggiunto un campo circa la quota di partecipazione che è diversa a seconda che uno faccia WORD oppure WINDOWS.

quindi ho due campi "quota di partecipazione" sia in CORSI che LIVELLI_INFORMATICA.

Dici che debba spostare questo campo in PROGRAMMI?

Il fatto è che non avviene quasi mai questa differenziazione a livello di PROGRAMMA.

anonimizzato
16-09-2006, 11:36
Ho capito anche ciclo...ok...va bene, ma non mi torno una cosa...
Posto così com'è in luoghi diversi non potresti realizzare cicli diversi...ti torna ? Secondo me cicli dovrebbe avere come FK programma_id e dovrebbe essere una relazione tutta chiave... L'ciclo_id in questo caso è una informazione non necessaria...

Ok forse ho capito:

intendi una tabella CICLI tipo:

PogrammaID
data_da
data_a

dove programmaID è PK e FK contemporaneamente.

quindi a tutti gli effetti una tabella sottoinsieme di PROGRAMMI che mette le informazioni del periodo solo per quei programmi che hanno cilci diversi giusto?

cionci
16-09-2006, 11:38
Per ogni luogo in cui il corso si svolge c'è una tupla nella relazione programmi, ok ?
In questa tupla di programmi quindi ci sono orari e giorni diversi per ogni luogo, ma non puoi avere cicli in date diverse !!!

Senza contare che hai gli stessi cicli per ogni livello del corso...

cionci
16-09-2006, 11:41
Ok forse ho capito:

intendi una tabella CICLI tipo:

PogrammaID
data_da
data_a

dove programmaID è PK e FK contemporaneamente.

quindi a tutti gli effetti una tabella sottoinsieme di PROGRAMMI che mette le informazioni del periodo solo per quei programmi che hanno cilci diversi giusto?
No, la tabella deve essere tutta chiave...in pratica la PK è (PogrammaID,data_da,data_a)

Select * from Cicli where programma_id = XXXX;

ti ritorna tutti i cicli di un dato programma...

cionci
16-09-2006, 11:56
Ricapitolando i farei qualche modifica...a meno di non scriversi tutto a penna e portarla in una forma normale, io farei così:

Categorie(id_categoria (PK), nome, descrizione)
Corsi(id_corso (PK), id_categoria (PK), nome, descrizione)
Livelli(id_livello (PK), id_corso (FK), costi, rate, allievi, insegnanti e così via)
Luoghi(id_luogo (PK), ...così com'è ora)
Programmi(id_programma (PK), id_livello (FK), id_luogo (FK), orari vari)
Cicli(id_programma, da, a) tutta chiave

anonimizzato
16-09-2006, 12:08
Ricapitolando i farei qualche modifica...a meno di non scriversi tutto a penna e portarla in una forma normale, io farei così:

Categorie(id_categoria (PK), nome, descrizione)
Corsi(id_corso (PK), id_categoria (PK), nome, descrizione)
Livelli(id_livello (PK), id_corso (FK), costi, rate, allievi, insegnanti e così via)
Luoghi(id_luogo (PK), ...così com'è ora)
Programmi(id_programma (PK), id_livello (FK), id_luogo (FK), orari vari)
Cicli(id_programma, da, a) tutta chiave

Azz... però così in Livelli avrei una marea di dati ridondanti circa costi, rate, insegnanti, allievi ecc. che tranne per informatica ed altri pochi casi sono generici a livello di corso.

anonimizzato
16-09-2006, 12:16
Per ogni luogo in cui il corso si svolge c'è una tupla nella relazione programmi, ok ?




In questa tupla di programmi quindi ci sono orari e giorni diversi per ogni luogo,


Eatto perchè un uno o più programmi si possono svolgere nello stesso luogo


ma non puoi avere cicli in date diverse !!!


Non ho capito mi potresti fare un esempio?


Senza contare che hai gli stessi cicli per ogni livello del corso...


Si perchè più livelli di un corso si svolgono nello stesso periodo e poi, magari, il tutto riprende uguale in caso di nuovo ciclo.
Non vedo il problema :confused:

anonimizzato
16-09-2006, 12:51
Attenzione! NODO CRUCIALE che mi sono scordato di dire.

Se vedi nella tabella CORSI ho aggiunto dopo diversi campi un "campo_note" per gestire in modo discorsivo situazioni tipo nei corsi di inglese dove il costo è per tutti i livelli X ma per quelli del mattino il cost è Y.

Alla luce di questo di caspisce come da alcune eccezioni si noti che il costo è ad altezza di LIVELLO e non CORSO (anche se di solito è così).

Tuttavia dato che dal DB non devo fare delle query particolari ho pensato che valesse la pena violare questa regola di normalizzazione per avere meno ridondanza di dati.

cionci
16-09-2006, 13:23
Azz... però così in Livelli avrei una marea di dati ridondanti circa costi, rate, insegnanti, allievi ecc. che tranne per informatica ed altri pochi casi sono generici a livello di corso.
Allora fai altre due tabelle:

costi_e_rate(id, informazioni sui costi e sulle rate)
composizione_corsi(id, insegnante, alievi min, allievi max)

e in livello inserisci il riferimento a costi_e_rate_id e composizione_corsi_id...

cionci
16-09-2006, 13:30
Eatto perchè un uno o più programmi si possono svolgere nello stesso luogo

Non ho capito mi potresti fare un esempio?

Corso di informatica, luogo A, 3 giorni alla settimana: cicli 10/9 - 20/10, 21/10 - 20/11, 21/11 - 31/12
Corso di informatica, luogo B, 4 giorni alla settimana: cicli 10/9 - 20/10, 21/10 - 20/11, 21/11 - 31/12

Ovviamente non puoi avere gli stessi cicli !!! Il secondo corso dura meno...
Si perchè più livelli di un corso si svolgono nello stesso periodo e poi, magari, il tutto riprende uguale in caso di nuovo ciclo.
Non vedo il problema :confused:
Corso di informatica livello medio: cicli 10/9 - 20/10, 21/10 - 20/11, 21/11 - 31/12
Corso di informatica livello avanzato: cicli 10/9 - 29/10, 30/10 - 31/12
Una cosa così non la puoi avere ?

anonimizzato
16-09-2006, 13:45
Allora fai altre due tabelle:

costi_e_rate(id, informazioni sui costi e sulle rate)
composizione_corsi(id, insegnante, alievi min, allievi max)

e in livello inserisci il riferimento a costi_e_rate_id e composizione_corsi_id...

Uhm ... mi spiazza un pò sul come poi creare l'interfaccia.

Tra le altre cose ho un problemino sul giorni nel senso che un programma potrebbe essere:

INGLESE
Livello 1
Frequenza sett. 2 ore
Lunedì
18.00 - 20.00
...

oppure

INGLESE
Livello 1
Frequenza sett. 2 ore
Lunedì - Giovedì
18.00 - 19.00
...

Ciò con la frequenza settimanale divisa in due lezioni alla settimana da un'ora.
Per evitare un campo multivalore tipo lunedì-giovedì all'interno della tabella dovrei crearne una di collegamento dato che uno stesso programma si può svolgere in più giorni e ovviamente in uno stesso giorno (della settimana) si svolgono più CORSI e LIVELLI.

anonimizzato
16-09-2006, 13:49
Corso di informatica, luogo A, 3 giorni alla settimana: cicli 10/9 - 20/10, 21/10 - 20/11, 21/11 - 31/12
Corso di informatica, luogo B, 4 giorni alla settimana: cicli 10/9 - 20/10, 21/10 - 20/11, 21/11 - 31/12

Ovviamente non puoi avere gli stessi cicli !!! Il secondo corso dura meno...


Osservazione giusta ma in realtà non funziona così.

La frequenza settimanale è a livello di CORSO quindi tutti i corsi di informatica o di inglese ecc. hanno tot ore a settimana percui i cicli (dei programmi) coincidono, è per questo che esistono (i CICLI) infatti per avere modo di avere dei programmi coerenti che iniziamo e finiscono più o meno insieme (poi dipende dal giorno della settimana). ;)


Corso di informatica livello medio: cicli 10/9 - 20/10, 21/10 - 20/11, 21/11 - 31/12
Corso di informatica livello avanzato: cicli 10/9 - 29/10, 30/10 - 31/12
Una cosa così non la puoi avere ?

cionci
16-09-2006, 13:50
Ti conviene anche qui fare una ulteriore tabella Orari

Orari (id_programma, giorno, da, a) con PK (id_programma, giorno)

anonimizzato
16-09-2006, 14:00
Umh di questo passo la struttura verrà parecchio diversa da quella "pensata" :D in origine.

Non è che sia un male è solo che non riesco a capire più se quello che avevo fatto all'inizio era totalmente sbagliato oppure era una strada differente con PRO e CONTRO come qualsiasi altra.

anonimizzato
16-09-2006, 15:24
A meno di grosse anomalie alla fine credo che terrò questa struttura.


CREATE TABLE categorie_corsi (
categoria_corso_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
categoria_corso_nome VARCHAR(255) NOT NULL,
PRIMARY KEY(categoria_corso_id)
);

CREATE TABLE giorni (
giorno VARCHAR(255) NOT NULL,
PRIMARY KEY(giorno)
);

CREATE TABLE corsi (
corso_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
categoria_corso_id INTEGER UNSIGNED NOT NULL,
corso_nome VARCHAR(255) NOT NULL,
corso_frequenza_settimanale INTEGER UNSIGNED NOT NULL,
corso_iscrizione INTEGER UNSIGNED NOT NULL,
corso_iscrizione_note VARCHAR(255) NOT NULL,
corso_quota_partecipazione INTEGER UNSIGNED NOT NULL,
corso_quota_partecipazione_note VARCHAR(255) NOT NULL,
corso_prima_rata INTEGER UNSIGNED NOT NULL,
corso_prima_rata_note VARCHAR(255) NOT NULL,
corso_seconda_rata INTEGER UNSIGNED NOT NULL,
corso_seconda_rata_note VARCHAR(255) NOT NULL,
corso_terza_rata INTEGER UNSIGNED NOT NULL,
corso_terza_rata_note VARCHAR(255) NOT NULL,
saldo_prima_lezione ENUM('0','1') NOT NULL,
corso_durata INTEGER UNSIGNED NOT NULL,
corso_allievi_min INTEGER UNSIGNED NOT NULL,
corso_allievi_max INTEGER UNSIGNED NOT NULL,
corso_eta_min INTEGER UNSIGNED NOT NULL,
corso_metodo VARCHAR(255) NOT NULL,
corso_insegnante VARCHAR(255) NOT NULL,
corso_testi INTEGER UNSIGNED NOT NULL,
corso_inizio DATE NOT NULL,
corso_fine DATE NOT NULL,
corso_descrizione MEDIUMTEXT NOT NULL,
corso_numero_lezioni INTEGER UNSIGNED NULL DEFAULT null,
corso_numero_ore INTEGER UNSIGNED NULL DEFAULT null,
corso_numero_settimane INTEGER UNSIGNED NULL DEFAULT null,
PRIMARY KEY(corso_id)
);

CREATE TABLE livelli (
livello_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
corso_id INTEGER UNSIGNED NOT NULL,
livello_nome VARCHAR(255) NOT NULL,
livello_note VARCHAR(255) NOT NULL,
PRIMARY KEY(livello_id),
INDEX FK1(corso_id)
);

CREATE TABLE luoghi (
luogo_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
luogo_nome VARCHAR(255) NOT NULL,
luogo_indirizzo VARCHAR(255) NOT NULL,
PRIMARY KEY(luogo_id)
);

CREATE TABLE programmi (
programma_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
livello_id INTEGER UNSIGNED NOT NULL,
luogo_id INTEGER UNSIGNED NOT NULL,
orario_da TIME NOT NULL,
orario_a TIME NOT NULL,
PRIMARY KEY(programma_id),
INDEX FK1(luogo_id),
INDEX FK2(livello_id)
);

CREATE TABLE programmi_giorni (
programma_id INTEGER UNSIGNED NOT NULL,
giorno VARCHAR(255) NOT NULL,
PRIMARY KEY(programma_id,giorno)
);


CREATE TABLE cicli (
corso_id INTEGER UNSIGNED NOT NULL,
ciclo_da DATE NOT NULL,
ciclo_a DATE NOT NULL,
PRIMARY KEY(corso_id,ciclo_da,ciclo_a)
);