Lezione Precedente | Elenco Lezioni | Lezione Successiva |
Presentiamo adesso l'applicazione web che andremo a sviluppare nel corso delle prossime lezioni: ne vedremo velocemente le specifiche e svilupperemo gli schemi relazionale e logico del database sottostante. Lo sviluppo del programma vero e proprio sarà invece l'argomento della parte restante di questo corso.
All'ultimo compleanno Paolo ha ricevuto una quantità di regali doppioni inusitati. Ha deciso allora di sviluppare un'applicazione web che mostri un elenco degli oggetti desiderati e che sia congegnata in modo tale da aiutare i suoi amici a non regalare dei doppioni.
Tutti gli amici di Paolo che desiderano utilizzare l'applicazione devono essere registrati con una username ed una password. Per poter usare il sito occorre effettuare una procedura di login, al termine della quale viene presentata una lista di oggetti. La lista è suddivisa in categorie (ad esempio: fumetti, DVD, abbigliamento, etc ...). Cliccando su uno degli oggetti appare una pagina web con una descrizione dettagliata dello stesso e un mini-blog con cui gli utenti possono scambiarsi messaggi. Da questa pagina è possibile aggiungere un messaggio al blog o prenotare l'oggetto. Quando un oggetto viene prenotato, non potrà più essere prenotato da nessun altro: colui che ha fatto la prenotazione si sta infatti impegnando a cercarlo e possibilmente a comprarlo. Se l'utente compra effettivamente l'oggetto prenotato, può convalidare la prenotazione. Altrimenti, se non ci riesce o cambia idea, può annullare la prenotazione, e l'oggetto tornerà ad essere prenotabile dagli altri utenti.
Oltre a queste funzioni, deve esistere un utente speciale, la cui password è a conoscenza solo di Paolo, che è in grado di effettuare varie operazioni amministrative:
Infine, è prevista la possibilità di consultare l'elenco degli oggetti nella mancolista anche senza effettuare la procedura di login. In questo caso, però, l'applicazione funzionerà solo in lettura: sarà impossibile prenotare o inserire messaggi nel blog.
Lo schema che segue riassume quali sono le pagine principali che costituiranno la nostra applicazione, e come si naviga tra di esse:
Questo è il diagramma ER (Entità-Relazioni) del database che servirà a immagazzinare tutte le informazioni rilevanti all'applicazione.
Tutti gli attributi dovrebbero essere auto-esplicativi, tranne forse admin
nell'entità Utente, che è fondamentalmente un valore booleano che sta ad indicare se un determinato utente ha diritti di amministratore oppure no. Per quanto riguarda i due attributi descrizione
e descrizione lunga
dell'entità Oggetto, il primo è pensato per essere visualizzato nella pagina con l'elenco degli oggetti, il secondo nella pagina relativa al singolo oggetto. Ai messaggi e alle prenotazioni associamo la data e l'ora della loro creazione: servirà per visualizzare i messaggi del blog in ordine cronologico e per implementare la funzionalità di cancellazione delle vecchie prenotazioni. In tutte le entità abbiamo optato per una chiave primaria sintetica.
Adesso questo diagramma ER va convertito in uno schema logico. Il procedimento è più o meno sempre lo stesso: le entità e le relazioni "molti a molti" diventano tabelle, le relazioni "uno ad uno" ed "uno a molti" diventano chiavi esterne di una delle due tabelle coinvolte. Decidiamo di seguire questo schema pedissequamente. Nel caso della relazione prenotato
, questo comporta che gli attributi di tale relazione vengano aggiunti alla tabella che codifica l'entità Oggetto. Notare che, in questo caso, sarebbe ragionevole usare per la relazione prenotato
una tabella a parte, per separare logicamente tutto ciò che riguarda gli oggetti in sé da ciò che riguarda le loro prenotazioni. Tuttavia, per motivi didattici che è prematuro spiegare adesso, ne faremo a meno.
mysql> describe oggetti; +-------------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | nome | varchar(255) | NO | | NULL | | | descrizione | varchar(255) | NO | | NULL | | | descrizione_lunga | text | NO | | NULL | | | categoria_id | int(11) | NO | | NULL | | | utente_id | int(11) | YES | | NULL | | | dataora | datetime | YES | | NULL | | | confermato | tinyint(1) | YES | | NULL | | +-------------------+--------------+------+-----+---------+----------------+ 8 rows in set (0.00 sec) mysql> describe categorie; +-------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | nome | varchar(255) | NO | | NULL | | +-------+--------------+------+-----+---------+----------------+ 2 rows in set (0.00 sec) mysql> describe utenti; +----------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | username | varchar(16) | NO | UNI | NULL | | | password | char(40) | NO | | NULL | | | admin | tinyint(1) | NO | | 0 | | +----------+-------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) mysql> describe messaggi; +------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+----------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | testo | text | NO | | NULL | | | utente_id | int(11) | NO | | NULL | | | oggetto_id | int(11) | NO | | NULL | | | dataora | datetime | NO | | NULL | | +------------+----------+------+-----+---------+----------------+ 5 rows in set (0.00 sec)
Tutte le chiavi sintetiche primarie sono state implementate con campi di tipo intero AUTO_INCREMENT
. Il campo username
è stato dichiarato varchar(16)
, i campi di testo che non ci si aspetta siano troppo lunghi (come descrizione
o nome
) sono dichiarati varchar(255)
, mentre i campi potenzialmente molto lunghi sono stati dichiarati TEXT
. Il campo password
è dichiarato di tipo char(40)
per dei motivi che vedremo in una delle prossime lezioni.
Tutti i campi sono dichiarati NOT NULL
, tranne gli attributi e le chiavi esterne che provengono dalla relazione prenotato
, visto che la cardinalità minima dell'entità Oggetto in questa relazione è zero. Inoltre, il campo username
nella tabella utenti
è dichiaro UNIQUE
(come si evince dal valore UNI
nella colonna Key
): si vuole evitare infatti che esistano due utenti con la stessa username.
È possibile scaricare lo script mancolista.sql che contiene i comandi SQL necessari a creare le tabelle qui sopra (già riempite con alcuni dati).
Trasformare le tabelle di cui sopra in modo che utilizzino il meccanismo di memorizzazione InnoDB, ed inserire i vincoli di integrità referenziale tra le tabelle nei casi in cui ciò è possibile.
Scrivere una query che restituisca l'elenco di tutti gli oggetti che non sono stati prenotati.
Scrivere una query che restituisca il numero di oggetti presenti nel database per ogni categoria.
Scrivere una query che restituisca le categorie ordinate sulla base del numero di prenotazioni confermate di oggetti di quella categoria.
Lezione Precedente | Elenco Lezioni | Lezione Successiva |