Realizzazione del database del sito: Frieund.com

 Progetto d'esame del corso di “Basi di Dati e Sistemi Informativi”
Realizzazione del database del sito: Frieund.com
Università degli Studi di Urbino “Carlo Bo”
Facoltà di Scienze e Tecnologie
Corso di Laurea in Informatica Applicata
Anno Accademico 2008/2009
MONACCHI ANDREA - Matricola 227377
“L'ignoranza è l'origine di tutti i mali” Socrate
Progettazione database del sito Frieund.com
Indice:
1. Introduzione............................................................................................................................p.5
L'Europa Il sito frieund.com e la necessità del database
2. Analisi dei requisiti..................................................................................................................p.6
Definizione dei target
Descrizione del problema
Analisi dei problemi
Correzione ambiguità
Glossario dei concetti principali
3. Progettazione concettuale........................................................................................................p.14
sviluppo del modello E/R sui vari blocchi
Integrazione dei blocchi in un unico schema
4. Progettazione logica.................................................................................................................p.19
• ottimizzazione dello schema E/R in base a:
4.1.1. volume dei dati
4.1.2. descrizione delle operazioni
4.1.3. analisi dei costi
•
•
•
•
semplificazione
traduzione
normalizzazione
MySQL:
4.5.1. realizzazione dello schema di database relazionale
4.5.2. definizione delle operazioni
5. Progettazione fisica.................................................................................................................p.61
• analisi del costo di accesso ai dati
6. Implementazione interfaccia....................................................................................................p.72
• descrizione applicazione
• elenco allegati
7. Bibliografia..............................................................................................................................p.80
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 3 di 80
Progettazione database del sito Frieund.com
“Se in un primo momento l'idea non è assurda, allora non c'è nessuna speranza che si realizzi”.
Albert Einstein
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 4 di 80
Progettazione database del sito Frieund.com
1. Introduzione
In questo paragrafo descriveremo velocemente le motivazioni che hanno portato all'implementazione di una base di dati e sui principali obiettivi e vincoli anteposti nella realizzazione di tale progetto.
1.1 L'Europa
Siamo nel 2009, ormai da tempo portiamo nelle nostre tasche spiccioli particolari che richiamano il nome di un continente, da anni non siamo più chiusi ai nostri piccoli confini ma viviamo in un mercato comune, monete che portano i segni di anni di tensioni e di un passato non molto lontano in cui siamo stati nemici almeno una volta, un tentativo di integrazione in un avvenire sempre meno rassicurante per il genere umano che tenta la carta della collaborazione, un integrazione tra milioni di persone, multiculturale e interreligiosa, una sfida del nuovo millennio che ai più scettici può apparire utopica ma che crea stabilità e sicurezza.
Su questo entusiasmo nasce l'idea di Frieund, un sito internet che dovrebbe farsi partecipe proprio di questa voglia di riscatto e di pubblicità della propria terra, seguendo quelle che sono le linee e i principi guida dell'integrazione europea, nel rispetto delle diversità e delle tradizioni che sono la vera ricchezza e il vero patrimonio da custodire gelosamente e costituiscono un passato e una base per il nostro futuro.
In un Europa di 27 paesi, è sempre più attuale il problema e la necessità di un confronto attivo che porti a conoscenza delle problematiche comuni e permetta l'insegnamento di certi principi nelle nuove generazioni. Per tali motivi è stato scelto come target primario l'adolescente, abituato alle nuove tecnologie, creativo e interattivo. Il sito prenderà la forma di un social network mantenendo quello che è il suo scopo di creare scambio di persone e idee.
1.2 La necessità di raccogliere informazioni
Per poter gestire tali servizi è necessario poter memorizzare i dati inerenti le persone e le azioni coinvolte, da qui nasce la necessità di una base di dati informatica (database) che permetta un accesso veloce e semplice a ogni utente remoto che ne faccia richiesta, sia esso in Finlandia o a Cipro.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 5 di 80
Progettazione database del sito Frieund.com
2. Analisi dei requisiti
In questo capitolo definiremo quali sono i nostri target e in quale modo vogliamo ottenere il raggiungimento del loro bisogno emozionale.
2.1 Definizione dei target
Target
Primario(adolescente) Secondario (universitario)
Terziario (famiglia)
Bisogno emozionale
Socializzazione, appartenenza ad un gruppo ed espressione di se stessi
Curiosità, innovazione, moda, alternatività, originalità, Passatempo, relax
esclusività
Stile del servizio
Giovanile, informale, aggregante, un po' aggressivo, ribelle
Dinamico, veloce, esclusivo, Familiare, rassicurante, alla moda, efficiente, semplice ed economico, innovativo
calmo e rilassante
età
11­25 anni
20­30 anni
30­60 anni
Livello reddito
basso
Medio basso
medio
Livello istruzione
Medio / medio basso
Alto
Medio/ medio basso
Occupazione
studente
Studente / ricercatore
Lavoratore (medio)
Frequenza uso internet alta
Medio alta
Medio bassa
Punti di accesso
Casa /scuola
Casa / scuola / wifi campus
casa
Veloc. Connessione
adsl
adsl
Pstn /adsl
Tipo computer
windows
Mac os/ linux / windows
windows
Browser
IE explorer / firefox
Safari/ firefox /IExplorer
IE explorer
Portatile (1280x800)
Fisso (1024x768)
community
Ricerche web
Viaggi, notizie, ricerche
Interessi
Community, messaggistica
Scambi all'estero, community, Ricette, notizie su europa scambio informazioni
e integrazione, normative
Personalità
Curiosa e dinamica, creativa e informale
Ambiziosa e potenzialmente ricca per la creazione di contenuti di buon livello
Profilo demografico
Rapporto con le tecnologie
Risoluz. Monitor
Comportamento online
Portatile/fisso 1280x800 | 1024x768
Attitudini
ANDREA MONACCHI ­ A.A. 2008/2009
Interessata e curiosa ma anche poco informata sulle nuove tecnologie
Pagina 6 di 80
Progettazione database del sito Frieund.com
Target
Primario(adolescente) Secondario (universitario)
Terziario (famiglia)
Stile di vita
Divertimento e tecnologia, giovanile
Relativamente frenetico, internet come passatempo, per Frenetico e impegnato, alcuni come fonte di notizie e internet come passatempo
stile di vita
Comportamento sul sito
Partecipe, dinamico, crea e scambia contenuti
Lettore e talvolta creatore di contenuti
Esperienza on line
Blog, social network, Ricerche web, tecnologia, mail e istant messaging informazioni accademiche
spettatore
Ricerche web, mail, notizie
Dai tre target si intuisce che il sito dovrà:
Rendere l'esperienza del visitatore la più facile, unica ed emotivamente coinvolgente possibile; dovrà dare una sensazione di accoglienza allo studente adolescente, le funzionalità dovranno essere chiare e rapide da raggiungere per l'universitario, che mirerà al conseguimento dell'obiettivo in modo efficace; infine dovrà divenire zona calma e tranquillizzante dove muoversi con serenità nel caso delle famiglie.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 7 di 80
Progettazione database del sito Frieund.com
2.2 Descrizione del problema
Per una maggiore intuitività elenchiamo i servizi offerti sotto forma di tabella:
Servizio / canale associato
Travelling
Hosting (scambi culturali e/o gemellaggi)
Ricette
Specialità dei paesi europei
Interesse
Target 1 e 2
Target 3
Eu!
Eu! City con la visualizzazione delle città
Storia integrazione europea
Le lingue
Le caratteristiche degli stati membri
Sondaggi e valutazione sull'interesse del sito
Interesse generale
Community
Profili degli utenti iscritti (stile Blog)
Target 1 e 2
Pannello di controllo personale
Wow
Foto documentative dei paesi europei
Interesse generale
Riassumendo le sezioni che necessiteranno di un utilizzo del database saranno:
­ Hosting per i dati relativi agli scambi culturali
­ Ricette che conterrà tutti i piatti inseriti dagli utenti
­ Eu! City per la memorizzazione delle città europee e la loro posizione sulla cartina
­ Community che visualizzerà i profili e darà modo di gestire i propri dati
­ Un archivio degli utenti iscritti e dei loro privilegi
­ Wow che conterrà tutte le informazioni relative agli scatti fotografici
Per motivi di carico dei dati è stato deciso di staccare il problema delle foto e affrontarlo in seguito, la nostra base di dati quindi sarà atta all'archiviazione degli utenti e della loro esperienza on line.
Vista la complessità e la partecipazione di componenti di natura diversa nel problema è stata decisa la scomposizione dello stesso in più parti che verranno poi ricomposte in seguito nello schema concettuale complessivo.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 8 di 80
Progettazione database del sito Frieund.com
2.3 Analisi dei problemi
Hosting
* Un utente può ospitare un altro utente
* Ogni utente che ospita ha una sua abitazione
* Ogni abitazione ha un suo indirizzo (che ne permetta la geolocalizzazione), una foto, un numero di posti, un costo per persona al giorno e informazioni aggiuntive
* Ogni abitazione si trova in una città, ogni città è contenuta in una nazione
* Ogni città ha un suo nome, ma città omonime possono trovarsi in nazioni diverse
* Ogni nazione ha un suo codice (vedi codifica nazioni)
* Ogni utente ospite può lasciare una valutazione riferita alla sua esperienza in una abitazione
* Ogni valutazione si compone di un voto (in decimi), un commento e una data di viaggio (arrivo) che permettano la tracciabilità delle esperienze europee degli utenti iscritti.
* Ogni valutazione deve rimanere memorizzata anche se l'utente che la scritta è eliminato
Ricette
* Ogni utente iscritto può inserire un piatto
* Ogni piatto è descritto da un nome, ingredienti ed un procedimento
* Un piatto è tipico di una città.
* Ogni città ha un nome ed è contenuta in una nazione, identificata da un codice (vedi codifica nazioni)
* Ogni piatto può appartenere ad una tra queste categorie: dolci, carne, pesce, pasta, verdure
* Ogni piatto è scritto da un utente identificato dal suo Username
* Ogni piatto è scritto in una lingua
* Ogni lingua ha un suo codice (lo stesso delle nazioni se supponiamo di avere una lingua per nazione)
Community
* Ogni utente (iscritto) ha un suo profilo
* Ogni profilo si compone di un messaggio personale, uno stile, una foto del contatto (vedi paragrafo sui tipi di dato) e un intervista (informazioni aggiuntive)
Utenti iscritti
In questa parte dobbiamo parlare di come raccogliere le informazioni sugli utenti iscritti. *
*
*
*
*
*
Sappiamo che dobbiamo raccogliere utenti di diverse nazioni europee, ogni nazione identificata dalla sua codifica internazionale.
Le credenziali che saranno richieste all'accesso (login) sono Username e Password
I dati personali sono il nome, l'email, la data di nascita, il sesso.
Ogni utente vive in una determinata città, che si trova in una nazione
Ogni utente parla una lingua, ogni lingua è identificata da un codice
Ogni utente ha un diverso privilegio di accesso, distingueremo un Amministratore, un Amministratore Locale e un utente semplice e in base a tale tipologia distingueremo in seguito le operazioni sui dati effettuabili
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 9 di 80
Progettazione database del sito Frieund.com
Città
*
*
*
*
Ogni città ha un nome,
Ogni città è posizionata in una nazione, ogni nazione è identificata da un codice
Posso avere città omonime in nazioni diverse
Ogni città ha un vettore (posx, posy) che permettono di localizzarla su una cartina
2.4 Correzione delle ambiguità intrablocco
In questo paragrafo effettiamo un controllo delle eventuali ambiguità creatisi internamente ogni blocco di problema. Problematica di cui si è comunque tenuto conto anche in fase di analisi dei requisiti, tentando di fornire elementi di base in modo preciso e il più univoco possibile.
Utente: Per Utente si intende un individuo correttamente iscritto e quindi presente nella sezione del database a esso dedicata.
Codice: Per codice si intende un sistema di identificazione univoco, che crei una biezione tra elementi nominati secondo un linguaggio reale e elementi nominati secondo un linguaggio costruito e quindi funzione di quello di partenza.
Nazione: Per nazione si intende un entità politica e fisica che accomuna più utenti, ogni nazione è quindi una partizione dell'insieme utenti iscritti. Per la codifica di tale concetto utilizzeremo le sigle internazionali (vedi sezione sui tipi di dato)
Abitazione
Per foto si intende la posizione sul file system del server di un immagine, puntatore che ne permetta il recupero e la visualizzazione ( vedi operazioni associate)
Per numero di posti si intende un valore intero che esprima la capacità ricettiva e le possibilità di intraprendere rapporti di scambio culturale tra utenti (iscritti).
Con costo per persona al giorno si intende un valore numerico intero che esprima il corrispettivo richiesto affinchè il rapporto di scambio sia possibile (valutato su una sola persona).
Ricette
Per piatto si intende un processo di creazione e composizione di alimenti che porta alla creazione di un unico prodotto.
Per nome di un piatto si intende una stringa di caratteri alfanumerici che serva a riconoscerlo da un altro (piatti con stesso nome differiscono per lingua), è quindi un concetto assunto in maniera diversa se confrontato con quello di nome di utente che non lo identifica univocamente in quanto ripetibile su più individui.
Per categoria di ricette si intende un sottoinsieme dell'insieme dei piatti per cui si attuano simili misure di manipolazione alimentare, piatti quindi accomunati da ingredienti simili o comunque surrogati, che possono essere visti anche identificando la famiglia di piatti.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 10 di 80
Progettazione database del sito Frieund.com
2.5 Glossario dei concetti principali
Hosting
Concetti base
Descrizione
Associazioni
ABITAZIONE
Indirizzo, numero posti disponibili, costo per persona al giorno, foto, informazioni aggiuntive
Utente proprietario (possesso)
Utente ospite (la valuta)
Città (posizione)
CITTA'
nome
Nazione (inserimento)
Abitazione (posizione)
NAZIONE
codice
Città (contenimento)
UTENTE
Username
Abitazione (possesso o ospite)
VALUTAZIONE
Voto, commento, data viaggio
Abitazione (riferimento)
Utente ospite (valutatore)
Ricette
Concetti base
Descrizione
Associazioni
PIATTO
Nome, ingredienti, procedimento
Utente (inseritore)
Paese (tipicità)
Categoria (appartenza)
CITTA'
nome
Piatto (tipicità)
Nazione (inserimento)
NAZIONE
codice
Città (contenimento)
UTENTE
Username
Piatto (inserimento)
LINGUA
codice
Piatto (lingua utilizzata)
Community (profilo utenti)
Concetti base
Descrizione
Associazioni
UTENTE
Username
Profilo (possesso)
PROFILO
Messaggio personale, stile, foto contatto, intervista
Utente (possesso)
Utenti iscritti
Concetti base
Descrizione
Associazioni
UTENTE
Nome, sesso, Username, Password, e­mail, data nascita
Città (residenza)
CITTA'
nome
Utente (luogo di residenza)
Nazione (appartenenza)
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 11 di 80
Progettazione database del sito Frieund.com
Utenti iscritti
NAZIONE
codice
Città (contenimento)
LINGUA
codice
Utente
Città
Concetti base
Descrizione
Associazioni
CITTA'
nome
Contenuta in una nazione
NAZIONE
codice
Contiene le città
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 12 di 80
Progettazione database del sito Frieund.com
2.6 Correzione delle ambiguità interblocco
Nella determinazione dei concetti principali dei blocchi indipendenti è possibile che siano stati inserite delle :
➢
➢
➢
sinonimie e omonimie
concetti troppo astratti
molteplicità di interpretazioni
Ambiguità
Un ambiguità la si riscontra nel concetto di codice, in particolare per quello delle nazioni e delle lingue in cui si suppone ci sia una lingua ufficiale utilizzata per ogni paese, anche se non è detto che un individuo (utente) di un dato paese debba necessariamente inserire contenuti nella lingua ufficiale del suo paese ma gli è in tal modo data possibilità di inserire contenuti ripetuti in diverse lingue o comunque differenti. Il concetto di codice corrisponde per i concetti che ne fanno uso essendo lo stesso tipo di dato.
Sinonimie e omonimie
Una sinonimia sta nel concetto di nome (come già definito trattando le ambiguità intrablocco) dove si fa differenza dal nome di un piatto dal nome di un utente
Un altra sinonimia è il concetto di foto, (foto utente e foto abitazione) entrambi tentano di rappresentare lo stesso concetto, la differenza è nella modalità con cui vi fanno riferimento.
Molteplicità di interpretazioni
Nella fase di analisi è stata evitata la rappresentazione diversa di concetti simili per facilitare le successive fasi di lavoro sui concetti.
Legami interblocco tra concetti base
L' utente è il concetto centrale, inserisce piatti, ospita altri utenti inserendo abitazioni, è ospitato e lascia valutazioni riguardo abitazioni di altri utenti, ha un suo profilo che può modificare in qualsiasi momento e visualizza quelli degli altri.
Tale relazione ci sarà utile nel momento della fusione dei vari schemi concettuali.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 13 di 80
Progettazione database del sito Frieund.com
3. Progettazione concettuale
In questa parte proveremo ad unire i concetti analizzati in precedenza creando legami e costruendo uno schema che descriva graficamente in maniera completa (cioè in modo sufficientemente espressivo nella rappresentazione) i requisiti.
3.1 Sviluppo dello schema E/R sui vari blocchi
Le strategie di sviluppo dello schema sono principalmente quattro:
➢
➢
➢
➢
Top­down, Bottom­up, Inside­out,
Strategia mista
Hosting
Utilizzando la strategia mista costruiamo lo schema E/R
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 14 di 80
Progettazione database del sito Frieund.com
Ricette
Tramite la strategia mista costruiamo lo schema anche per la sezione ricette
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 15 di 80
Progettazione database del sito Frieund.com
Community (profilo utenti)
Allo stesso modo con la strategia mista nel caso del profilo utente
Città
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 16 di 80
Progettazione database del sito Frieund.com
Utenti iscritti
Utilizzando la strategia mista costruiamo lo schema E/R
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 17 di 80
Progettazione database del sito Frieund.com
3.2 Integrazione dei vari blocchi in un unico schema
E' giunto il momento di fondere i schemi creati in un unico modello concettuale, tenendo conto in questa operazione delle problematiche e dei conflitti che potrebbero generarsi
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 18 di 80
Progettazione database del sito Frieund.com
4. Progettazione Logica
La progettazione logica è la serie di operazioni che ci permetterà di ricavare dal nostro modello concettuale (schema E/R) un modello logico basato su una particolare struttura, (reticolare, gerarchica, relazionale, ad oggetti).
La progettazione logica quindi ci seguirà nella realizzazione effettiva della nostra base di dati, che per la scelta del linguaggio di interrogazione sarà di tipo relazionale. Avremo quindi un effettiva traduzione del modello concettuale che passerà in quattro fasi distinte:
➢
Ottimizzazione
Dove valuteremo le prestazioni tenendo conto del volume dei dati e delle operazioni su essi
➢
Semplificazione
Dove tenteremo di eliminare i costrutti che rendono diversi i due modelli
➢
Traduzione
Che ci permetterà di passare dal modello E/R a quello relazionale associato
➢
Normalizzazione
Dove analizzeremo le dipendenze funzionali e tenteremo di prevenire eventuali anomalie e ridondanze dei dati
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 19 di 80
Progettazione database del sito Frieund.com
4.1 Ottimizzazione
Tentiamo di valorizzare il nostro schema concettuale quantificando il volume dei dati che lo popoleranno e le operazioni che agiranno su di essi.
4.1.1 Volume dei dati
Stime:
* ipotizzo 1.000.000 di utenti, ognuno con un profilo,
* 1% degli utenti dispone di un abitazione per il servizio di hosting
* lo 0,5 % degli utenti inserisce ricette
* il 5% degli utenti è ospitato da un altro
* Esistono circa 80.000 città in Europa (8.104 solo in Italia)
Stime di accesso dei relativi target:
Target 1
Spesso on line
1 accesso al giorno
Target 2
Target 3
Ogni tanto on line
1 accesso ogni 3 giorni
On line raramente
1 accesso ogni 15 giorni
La popolazione è suddivisa nel modo:
65% al target 1
20% al target 2
15% al target 3
Nel caso di 1.000.000 di utenti stimati avremo:
650.000 * 1 +
200.000 * 0,33 +
150.000 * 0,066 =
650.000 + 66.000 + 9900 = 725.900 accessi/giorno
Di questi considereremo un 20% inattivo, cioè 200.000 persone inattive su 1.000.000, persone regolarmente iscritte ma che non usufruiscono in modo continuo (e protratto nel tempo cosi che la frequenza ne dia un significativo apporto) del servizio.
Avremo:
520.000 utenti del target 1
160.000 utenti del target 2
120.000 utenti del target 3
Tale stima diminuisce il calcolo degli accessi giornalieri rispetto a quella precedentemente elaborata.
520.000 + (160.000 * 0,33) + (120.000 * 0,066) = 520.000 + 52.800 + 7.920 = 580.720 acc./giorno
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 20 di 80
Progettazione database del sito Frieund.com
Ora riportiamo le stime effettuate sul nostro schema concettuale: ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 21 di 80
Progettazione database del sito Frieund.com
4.1.2 descrizione delle operazioni
Stima della frequenza delle operazioni
Il calcolo è effettuato su 1.000.000 di utenti e 580.720 accessi giornalieri (vedi volume dati)
Utilizzando il numero di accessi costruisco una serie di schemi (con l'idea delle applicazioni che gestiranno i dati) come percorso dell'utente da una operazione (pagina) all'altra.
La figura sopra è un esempio della metodologia utilizzata per il calcolo (prima in percentuale e poi sugli accessi) della frequenza di attivazione.
Tipo di operazione
Stima attivazione
Visualizzazione abitazioni presenti in una data città
Visualizzazione valutazioni su una data abitazione
Visualizzazione abitazione di un dato utente proprietario
25% visualizzazione città
70% visualizzazione abitazione
30% visualizzazione città
Inserimento piatto tra ricette
Visualizzazione piatti di una certa città
Visualizzazione piatti inseriti da un utente
0,001% accessi
15% visualizzazione città
3% visualizzazione profilo utente
Visualizzazione del profilo di un utente
Visualizzazione utenti di una certa città
Aggiornamento del proprio profilo
3 * numero accessi al giorno
60% visualizzazione città
30% accessi
Login all'area riservata
Iscrizione al sito (inserimento nuovo utente)
Rimozione di un utente e aggiornamento del database
100% accessi
Visualizzazione di una città di una nazione sulla cartina
60% accessi
ANDREA MONACCHI ­ A.A. 2008/2009
1/1.000.000 accessi
Pagina 22 di 80
Progettazione database del sito Frieund.com
Elenco delle operazioni suddivise per area tematica:
Hosting
Descrizione operazione
Tipo accesso
Freq. attivazione
Visualizzazione abitazioni presenti in una data città
Visualizzazione valutazioni su una data abitazione
Visualizzazione abitazione di un dato utente proprietario
R
R
R
87.108
73.170
104.529
Tipo accesso
Freq. accesso
R/W
R
R
5,80
52.264,8
52.264,8
Tipo accesso
Freq. accesso
R
R
R/W
1.742.160
209.059,2
174.216
Tipo accesso
Freq. accesso
R
R/W
R/W
580.720
*
0,58
Descrizione operazione
Tipo accesso
Freq. accesso
Visualizzazione di una città di una nazione sulla cartina
R
348.432
Ricette
Descrizione operazione
Inserimento piatto tra ricette
Visualizzazione piatti di una certa città
Visualizzazione piatti inseriti da un utente
Community (profilo utente)
Descrizione operazione
Visualizzazione del profilo di un utente
Visualizzazione utenti di una certa città
Aggiornamento del proprio profilo
Utenti iscritti
Descrizione operazione
Login all'area riservata
Iscrizione al sito
Rimozione di un utente e aggiornamento del database
Città
*Non è possibile stabilire a priori il numero di ripetizioni di tale funzione dato che non si può prevedere il successo o l'insuccesso di un sito. Si può però immaginare che esso assuma una legge esponenziale che all'aumentare degli iscritti comporta un aumento di nuovi utenti aggregati alla community.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 23 di 80
Progettazione database del sito Frieund.com
4.1.3 Analisi dei costi
Prima di passare alla quantificazione del costo delle operazioni definite possiamo provare a ridurre la complessità di alcune porzioni del nostro schema.
Nel caso delle associazioni quali ad esempio la lingua (di cardinalità 1:1) è possibile semplificare il modello concettuale presentato sostituendo tale concetto (rappresentato come entità) con un attributo, riducendo cosi il costo di attraversamento e recupero dei dati.
Tale semplificazione non comporta modifiche sostanziali in quanto le cardinalità delle associazioni sono 1:1 e non sono stati posti vincoli sulla permanenza di tali dati nel database durante la fase di analisi dei requisiti, vincolo che sarebbe comunque rispettabile introducendo opportuni accorgimenti nelle applicazioni di gestione dei dati.
Osservando lo schema notiamo come tale situazione si presenta in modo simile per il concetto di città e nazione.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 24 di 80
Progettazione database del sito Frieund.com
Presentiamo ora di seguito le operazioni con i relativi costi
Hosting
Operazioni
Schema di navigazione
Visualizzazione abitazioni presenti in una data città
Tipo accesso
CITTA'
1 r
locata
0,125 r
ABITAZIONE
0,125 r
Totale
1,25 r
Totale * frequenza attivazione
108.885 r / giorno
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 25 di 80
Progettazione database del sito Frieund.com
Operazioni
Schema di navigazione
Visualizzazione valutazioni su una data abitazione
Tipo accesso
UTENTE
1 r
ha
1 r
ABITAZIONE
1 r
riferita
4 r
VALUTAZIONE
4 r
Totale
11 r
Totale * frequenza attivazione
804.870 r / giorno
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 26 di 80
Progettazione database del sito Frieund.com
Operazioni
Schema di navigazione
Visualizzazione abitazione di un dato utente proprietario
Tipo accesso
UTENTE
1 r
ha
1 r
ABITAZIONE
1 r
locata
1 r
CITTA'
1 r
Totale
5 r
Totale * frequenza di attivazione
522.645 r / giorno
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 27 di 80
Progettazione database del sito Frieund.com
Ricette
Operazioni
Schema di navigazione
Inserimento piatto tra ricette
Tipo accesso
PIATTO
1 w
CITTA'
1 r
tipico
1 w
inserisce
1 w
Totale
7 r
Totale * frequenza attivazione
7 * 5,80 = 40,6 r / giorno
Visualizzazione piatti di una certa città
Tipo accesso
CITTA'
1 r
tipico
0,0625 r
PIATTO
0,0625 r
Totale
1,125 r
Totale * frequenza di attivazione
58.797,9 r / giorno
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 28 di 80
Progettazione database del sito Frieund.com
Operazioni
Schema di navigazione
Visualizzazione piatti inseriti da un utente
Tipo accesso
UTENTE
1 r
inserisce
0,005 r
PIATTO
0,005 r
Totale
1,01 r
Totale * frequenza di attivazione
52.787,448 r / giorno
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 29 di 80
Progettazione database del sito Frieund.com
Community (profilo utente)
Operazioni
Schema di navigazione
Visualizzazione del profilo di un utente
Tipo accesso
UTENTE
1 r
vive
1 r
CITTA'
1 r
ha
1 r
PROFILO
1 r
Totale
5 r
Totale * frequenza attivazione
8.710.800 r / giorno
Visualizzazione utenti di una certa città
Tipo accesso
CITTA'
1 r
vive
12,5 r
UTENTE
12,5 r
Totale
26 r
Totale * frequenza di attivazione
5.435.539,2 r / giorno
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 30 di 80
Progettazione database del sito Frieund.com
Operazioni
Schema di navigazione
Aggiornamento del proprio profilo
Tipo accesso
UTENTE
1 r
ha
1 r
PROFILO
1 r
1 w
Totale
5 r
Totale * frequenza di attivazione
871.080 r / giorno
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 31 di 80
Progettazione database del sito Frieund.com
Utenti
Operazioni
Schema di navigazione
Login all'area riservata
Tipo accesso
UTENTE
1 r
Totale
1 r
Totale * frequenza attivazione
580.720 r / giorno
Rimozione utente dal sito
Tipo accesso
UTENTE
1 r + 1 w
ha
1 r
PROFILO
1 r + 1 w
vive
1 r + 1 w
ha
1 r + 1 w
ABITAZIONE
1 r + 1 w
Totale
16 r
Totale * frequenza attivazione
9,28 r / giorno
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 32 di 80
Progettazione database del sito Frieund.com
Operazioni
Schema di navigazione
Iscrizione al sito (inserimento nuovo utente)
Tipo accesso
Disponibilità
username
UTENTE
1 r
Inserimento
utente
UTENTE
1 w
vive
1 w
Inserimento
profilo
ha
1 w
PROFILO
1 w
Totale
9 r
Il numero di letture nel caso della disponibilità dello username dipende fortemente dal numero di tentativi.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 33 di 80
Progettazione database del sito Frieund.com
Eu! City
Operazioni
Schema di navigazione
Visualizzazione di una città sulla cartina
Tipo accesso
CITTA'
1 r
Totale
1 r
Totale * frequenza attivazione
1 * 348.432 = 348.432 r / giorno
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 34 di 80
Progettazione database del sito Frieund.com
Valutazione sul partizionamento dell'entità utente
Operazioni
Visualizza abitazioni di un dato utente
Visualizza piatti inseriti da un utente
Visualizza il profilo di un utente
Aggiornamento del profilo di un utente
Visualizza utenti di una certa città
Login all'area riservata
Iscrizione al sito
Rimozione di un utente e aggiornamento database
Note
Non fanno uso dell'attributo password ma si servono del campo username e nel caso della visualizzazione del profilo utente anche di alcuni dati personali.
Fanno uso del campo password
Possiamo pensare di scorrelare le due entità dati personali e dati accesso in quanto solo le operazioni di iscrizione al sito e di rimozione utente iscritto fanno uso degli attributi di entrambe le entità, operazioni che non sono invocate frequentemente. ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 35 di 80
Progettazione database del sito Frieund.com
Tale modifica però non fa che peggiorare la nostra (comunque frequente) operazione di login all'area riservata. Operazione
Login all'area riservata
Senza partizionamento
UTENTE 1 r
Con partizionamento
DATI PERSONALI
1 r
e
1 r
DATI ACCESSO
1 r
580.720 *
3 r
totale
1.742.160 r/day
totale: 580.720 r / day
Nota:
Tale modifica nel mio schema comporta un peggioramento delle prestazioni in quanto devo comunque leggere la chiave tra i dati personali
Dove sta la convenienza del nostro partizionamento se non fa che peggiorare il costo di accesso ai dati interessati dalle operazioni?
Per risolvere questo problema possiamo pensare ad un attributo derivato e ridondato nell'entità dati accesso, in sostituzione della chiave importata in modo da eliminare l'associazione e la foreign key e riducendo in tal modo i costi di accesso in modo drastico.
Quanto assunto comporta quindi modifiche importanti al costo di accesso ai dati.
Ovviamente le operazioni che risulteranno avere un incremento significativo nelle performance saranno quelle che fanno uso del campo password che troveranno una tabella più snella su cui agire.
Login all'area riservata
DATI ACCESSO
1 r
580.720 * 1
580.720 r/day
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 36 di 80
Progettazione database del sito Frieund.com
Iscrizione utente
Disponibilità username
Inserimento utente
DATI ACCESSO
1 r
DATI ACCESSO
1 w
identità
1 w
DATI PERSONALI
1 w
vive
1 w
ha
1 w
PROFILO
1 w
Inserimento profilo
13 r
Rimozione utente
Nel caso della rimozione di un utente i dati di accesso sono comunque mantenuti memorizzati per dare possibilità di poter riaccedere al sito in futuro e riattivare i propri dati personali. Quindi in questo caso il costo dell'operazione di rimozione rimane invariato.
Per concludere, il partizionamento e scorrelazione dell'entità utente apporta un lieve e trascurabile aumento di accessi al disco solo nel caso di un operazione poco frequente quale è quella di iscrizione. Un prezzo da pagare se rapportato con il miglioramento prestazionale raggiunto nell'operazione di login.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 37 di 80
Progettazione database del sito Frieund.com
4.2 Semplificazione
Il processo di semplificazione comprende:
➢ semplificazione delle gerarchie
➢ semplificazione degli attributi composti
➢ semplificazione degli attributi ripetuti
➢ semplificazione degli identificatori esterni
Semplificazione delle gerarchie
Hosting
Tornando allo schema E/R pre­ottimizzazione notiamo come sia stata introdotta una gerarchia.
Tale accorgimento è stato pensato per dare maggiore espressività al nostro modello ma non era richiesto da alcun requisito. Nella fase di semplificazione notiamo come questo possa causare un inutile aumento del costo dei dati. La gerarchia è inoltre parziale e sovrapposta. Proviamo a semplificare tali concetti collassandoli nell'entità padre, non introdurremo alcun selettore in quanto le specializzazioni sono sovrapposte e hanno le stesse caratteristiche
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 38 di 80
Progettazione database del sito Frieund.com
Utente
La gerarchia è completa ed esclusiva posso quindi pensare di rimuovere l'entità padre scorrelando le specializzazioni.
Questo garantirebbe una suddivisione del carico dei dati su più porzioni dello schema.
Visto però che il numero di “amministratori” e “amministratori locali” sarà molto basso ci ritroveremo comunque con l'entità utente semplice con un numero di istanze pressochè uguale a quello di “dati accesso”.
L'intuizione ci spinge ad un altra possibilità, collassare la gerarchia in una singola entità, introducendo un attributo selettore finalizzato alla diversificazione e al riconoscimento dei diversi concetti. Chiameremo tale attributo “privilegio”.
Questa modifica non comporta alcun peggioramento prestazionale del nostro schema E/R (a parte il peso dell'entità che aumenta a causa della memorizzazioni dei dati relativi all'attributo privilegio). Non è necessario ricalcolare perciò il costo di accesso per le varie operazioni che fanno uso di tale porzione di schema.
Ricette
La gerarchia è totale ed esclusiva e questo ci permette di usare una qualsiasi delle 3 soluzioni proposte.
Per la scelta dovremo valutare la differenza di prestazioni che la differente configurazione comporta. Scartiamo la 3° soluzione che prevede la sostituzione della gerarchia con associazioni e risulta costosissima nelle operazioni che attraversano tutte le specializzazioni.
Visto che le nostre operazioni fanno uso di tutte le specializzazioni risulta costosa anche la soluzione che prevede la rimozione dell'entità padre. La soluzione meno costosa sotto il profilo dell'ottimizzazione risulta perciò la 1°, collassiamo la gerarchia in una sola entità dove introdurremo l'attributo “categoria” come selettore.
Questa analisi non tiene conto della dimensione di ogni istanza dell'entità per cui in tale calcolo non ci è possibile capire se è conveniente l'utilizzo della prima soluzione o se a discapito del numero di accessi possiamo alleggerire la dimensione dell'entità suddividendo le istanze nelle varie specializzazioni.
Seguendo la prima soluzione, come è stato fatto, non avremo cambiamenti sul costo delle operazioni calcolate precedentemente
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 39 di 80
Progettazione database del sito Frieund.com
Semplificazione degli identificatori esterni
La seconda operazione comporta una modifica sulle operazioni di accesso. Dobbiamo perciò rivalutarne i costi:
Visualizzazione abitazione di un utente proprietario
Visualizzazione valutazioni su una abitazione
ABITAZIONE
1 r
ABITAZIONE
1 r
locata
1 r
riferita
4 r
CITTA'
1 r
VALUTAZIONE
4 r
3 r
Costo pre­semplificazione
5 r
9 r
Costo pre­semplificazione
11 r
Totale * frequenza di attivazione
Totale * frequenza di attivazione
5 * 104.529 = 522.645 r /day
9 * 73.170 = 658.530 r /day
Tale modifica comporta quindi una riduzione del costo delle operazioni.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 40 di 80
Progettazione database del sito Frieund.com
4.3 Traduzione
I processi di ottimizzazione e traduzione ci hanno portato al seguente schema concettuale:
Procediamo con il processo di traduzione:
Città(nome, nazione, posx, posy)
Dati_accesso(username, password, privilegio)
Utente(username, nome, sesso, lingua, data_nascita, mail, nome_città, nazione)
Piatto(nome, lingua, categoria, procedimento, ingredienti, nome_città, nazione, utente)
Profilo(utente, messaggio_personale, intervista, foto, stile)
Valutazione(ospite, data, voto, commento, proprietario, indirizzo)
Abitazione(proprietario, indirizzo, costo_giorno, numero_posti, informazioni_aggiuntive)
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 41 di 80
Progettazione database del sito Frieund.com
4.4 Normalizzazione
Analizzando gli schemi di relazione notiamo essi siano già in 3NF:
Città(nome, nazione, posx, posy)
Dati_accesso(username, password, privilegio)
Utente(username, nome, sesso, lingua, data_nascita, mail, nome_città, nazione)
Abitazione(proprietario, indirizzo, foto, costo_giorno, numero_posti, informazioni_aggiuntive, nome_città, nazione)
Piatto(nome, lingua, categoria, ingredienti, procedimento, nome_città, nazione, utente)
Profilo(utente, messaggio_personale, intervista, foto, stile)
Valutazione(ospite, data, voto, commento, proprietario, indirizzo)
Profilo, utente, dati_accesso sono intrinsecamente in seconda forma normale in quanto la chiave è attributo semplice. Nel caso degli altri schemi di relazione è necessario controllare le dipendenze funzionali e la presenza di eventuali determinanti sottoinsieme della chiave.
La terza forma normale tenta di risolvere la condizione limite della seconda forma normale per cui anche in presenza di identificatore semplice possiamo avere determinanti che comportano dipendenze di attributi da altri attributi non chiave. (dipendenza transitiva)
Analizzando proprio tali dipendenze è stato verificato proprio come gli schemi siano in 3NF, questo anche grazie ad un attenta pianificazione e progettazione nelle fasi precedenti che hanno permesso di evitare ridondanze o situazioni anomale che si sarebbero potute presentare in fase di aggiornamento dei dati.
Possiamo anche verificare se i nostri schemi sono in forma normale di Boyce Codd, per raggiungere tale condizione dovremo garantire che ogni determinante nel nostro schema possa svolgere anche funzione di chiave (chiave candidata). Scorrendo i vari schemi si può notare come essi non abbiano determinanti tra i vari attributi. Gli schemi sono quindi anche in forma normale di Boyce­Codd.
La procedura di normalizzazione quindi non ha comportato modifiche al nostro schema relazionale.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 42 di 80
Progettazione database del sito Frieund.com
4.5 MySQL
MySql è un RDBMS (sistema di gestione di database relazionali) che prevede l'utilizzo del linguaggio di interrogazione, definizione e manipolazione Sql per la gestione dei dati. Dagli schemi di relazione ottenuti in fase di traduzione e normalizzazione dovremo implementare tali concetti in tabelle.
Prima di tutto dobbiamo però definire domini e tipi di dato che andranno a popolare i campi della nostra tabella.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 43 di 80
Progettazione database del sito Frieund.com
4.5.1 Realizzazione dello schema di database relazionale
In questa parte definiamo la struttura delle nostre tabelle, con molta accortezza per evitare inutili sprechi di memoria
Città
Attributo
Tipo
Proprietà
nome
Varchar(40)
PRIMARY KEY
nazione
Char(3)
PRIMARY KEY
posx
Unsigned smallint(4)
NOT NULL
posy
Unsigned smallint(4)
NOT NULL
Attributo
Tipo
Proprietà
username
Varchar(30)
PRIMARY KEY
password
Char(40)
NOT NULL
privilegio
Enum('A','L','S')
NOT NULL
Attributo
Tipo
Proprietà
username
Varchar(30)
PRIMARY KEY
nome
Varchar(30)
NOT NULL
sesso
Enum('M','F')
NOT NULL
lingua
Char(3)
NOT NULL
data_nascita
date
NOT NULL
mail
Varchar(40)
NOT NULL
nome_città
Varchar(40)
NOT NULL
nazione
Char(3)
NOT NULL
Attributo
Tipo
Proprietà
utente
Varchar(30)
PRIMARY KEY
messaggio_personale
text
NOT NULL
intervista
Unsigned smallint(4)
NOT NULL
foto
Unsigned smallint(1)
NOT NULL
stile
Unsigned tinyint(2)
NOT NULL
dati_accesso
utente
profilo
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 44 di 80
Progettazione database del sito Frieund.com
abitazione
Attributo
Tipo
Proprietà
pro prietario
Varchar(30)
PRIMARY KEY
ind irizzo
Varchar(60)
PRIMARY KEY
foto
Char(14)
NOT NULL
costo_giorno
Unsigned smallint(3)
NOT NULL
numero_posti
Unsigned tinyint(2)
NOT NULL
informazioni_aggiuntive
Unsigned smallint(4)
NOT NULL
nome_città
Varchar(40)
NOT NULL
nazione
Char(3)
NOT NULL
Attributo
Tipo
Proprietà
nome
Varchar(40)
PRIMARY KEY
lin gua
Char(3)
PRIMARY KEY
categoria
Enum('V','D','C','F','P')
NOT NULL
ingredienti
text
NOT NULL
procedimento
text
NOT NULL
nome_città
Varchar(40)
NOT NULL
nazione
Char(3)
NOT NULL
utente
Varchar(30)
NOT NULL
Attributo
Tipo
Proprietà
ospite
Varchar(30)
PRIMARY KEY
data
date
PRIMARY KEY
voto
Unsigned tinyint(2)
NOT NULL
commento
text
NOT NULL
proprietario
Varchar(30)
NOT NULL
indirizzo
Varchar(60)
NOT NULL
piatto
valutazione
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 45 di 80
Progettazione database del sito Frieund.com
Note sulla struttura e tipi di dato utilizzati
Codice nazione, lingua ­> char(3)
B
DK
D
EL
E
F
IRL
I
L
NL
A
P
FIN
S
UK
BG
CY
CZ
EE
HU
LV
LT
MT
PL
RO
SK
SI
Profilo.foto ­> unsigned smallint(1)
'0'
'1'
'2'
Foto non caricata, contatto maschile
Foto non caricata, contatto femminile
ESEMPIO
Foto caricata dal contatto
Valutazione.voto ­> Unsigned tinyint(2)
è un valore numerico da 0 a 10 che esprime il grado di qualità del rapporto di hosting
abitazione.costo_giorno ­> Unsigned smallint(3)
valore numerico intero(si pone che non siano i centesimi di euro a fare la differenza in un prezzo), il prezzo massimo è quindi 999 euro (cifra comunque teorica e fuori dalla portata dei target assunti)
profilo.stile ­> Unsigned tinyint(2)
valore numerico (fino a 99) che richiama l'identificativo dello stile del profilo di un utente
piatto.categoria ­> Enum('V','D','C','F','P')
richiama le tipologie verdure, dolci, carne, pesce, pasta
intervista ­> Unsigned smallint(4), informazioni_aggiuntive ­> Unsigned smallint(4)
Rappresentano in modo analogo la stessa tipologia di dato, valori numerici di 4 cifre decimali.
Tale valore è poi convertito in codice binario di 2^4=16 cifre e stampato cifra per cifra per valorizzare le domande poste nel profilo utente o nella pagina della abitazione.
Abitazione.foto ­> Char(14)
Mentre nel caso del profilo avevamo una sola foto corrispondente a ogni utente, in questo caso possiamo avere utenti con più abitazioni, il campo foto deve mantenere la relazione con la abitazione ma deve essere necessariamente univoco. È introdotto perciò un codice di identificazione che tiene traccia anche del timestamp di inserimento nel database.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 46 di 80
Progettazione database del sito Frieund.com
Comandi Sql per l'implementazione del database
Tramite la sintassi Sql (structured query language) abbiamo potuto descrivere la struttura del nostro schema relazionale.
Per poter capire tutta la fase di creazione riportiamo il Dump della nostra base di dati.
--MySQL Dump
--- Host: 62.149.150.72
-- Generato il: 22 apr, 2009 at 12:02 AM
-- Versione MySQL: 5.0.68
-- Versione PHP: 5.2.9
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
/*!40101
/*!40101
/*!40101
/*!40101
SET
SET
SET
SET
@OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
@OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
@OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
NAMES utf8 */;
--- Database: `Sql180545_1`
--- ---------------------------------------------------------- Struttura della tabella `abitazione`
-CREATE TABLE IF NOT EXISTS `abitazione` (
`proprietario` varchar(30) collate utf8_bin NOT NULL,
`indirizzo` varchar(60) collate utf8_bin NOT NULL,
`foto` char(14) collate utf8_bin NOT NULL,
`costo_giorno` smallint(3) unsigned NOT NULL,
`numero_posti` tinyint(3) unsigned NOT NULL,
`informazioni_aggiuntive` smallint(4) unsigned NOT NULL,
`nome_citta` varchar(40) collate utf8_bin NOT NULL default '',
`nazione` char(3) collate utf8_bin NOT NULL,
PRIMARY KEY (`proprietario`,`indirizzo`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `abitazione`
--- ---------------------------------------------------------- Struttura della tabella `citta`
-CREATE TABLE IF NOT EXISTS `citta` (
`nome` varchar(40) collate utf8_bin NOT NULL,
`nazione` char(3) collate utf8_bin NOT NULL,
`posx` smallint(4) unsigned NOT NULL,
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 47 di 80
Progettazione database del sito Frieund.com
`posy` smallint(4) unsigned NOT NULL,
PRIMARY KEY (`nome`,`nazione`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `citta`
--- ---------------------------------------------------------- Struttura della tabella `dati_accesso`
-CREATE TABLE IF NOT EXISTS `dati_accesso` (
`username` varchar(30) collate utf8_bin NOT NULL,
`password` char(40) collate utf8_bin NOT NULL,
`privilegio` enum('A','L','S') collate utf8_bin NOT NULL,
PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `dati_accesso`
--- ---------------------------------------------------------- Struttura della tabella `piatto`
-CREATE TABLE IF NOT EXISTS `piatto` (
`nome` varchar(40) collate utf8_bin NOT NULL,
`lingua` char(3) collate utf8_bin NOT NULL,
`categoria` enum('V','D','C','F','P') collate utf8_bin NOT NULL,
`ingredienti` text collate utf8_bin NOT NULL,
`procedimento` text collate utf8_bin NOT NULL,
`nome_citta` varchar(40) collate utf8_bin NOT NULL,
`nazione` char(3) collate utf8_bin NOT NULL,
`utente` varchar(30) collate utf8_bin NOT NULL,
PRIMARY KEY (`nome`,`lingua`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `piatto`
--- ---------------------------------------------------------- Struttura della tabella `profilo`
-CREATE TABLE IF NOT EXISTS `profilo` (
`utente` varchar(30) collate utf8_bin NOT NULL,
`messaggio_personale` text collate utf8_bin NOT NULL,
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 48 di 80
Progettazione database del sito Frieund.com
`intervista` smallint(4) unsigned NOT NULL,
`foto` tinyint(1) unsigned NOT NULL,
`stile` tinyint(2) unsigned NOT NULL,
PRIMARY KEY (`utente`),
KEY `utente` (`utente`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `profilo`
--- ---------------------------------------------------------- Struttura della tabella `utente`
-CREATE TABLE IF NOT EXISTS `utente` (
`username` varchar(30) collate utf8_bin NOT NULL,
`nome` varchar(30) collate utf8_bin NOT NULL,
`sesso` enum('M','F') collate utf8_bin NOT NULL,
`lingua` char(3) collate utf8_bin NOT NULL,
`data_nascita` date NOT NULL,
`mail` varchar(40) collate utf8_bin NOT NULL,
`nome_citta` varchar(40) collate utf8_bin NOT NULL,
`nazione` char(3) collate utf8_bin NOT NULL,
PRIMARY KEY (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `utente`
--- ---------------------------------------------------------- Struttura della tabella `valutazione`
-CREATE TABLE IF NOT EXISTS `valutazione` (
`ospite` varchar(30) collate utf8_bin NOT NULL,
`data` date NOT NULL,
`voto` tinyint(2) unsigned NOT NULL,
`commento` text collate utf8_bin NOT NULL,
`proprietario` varchar(30) collate utf8_bin NOT NULL,
`indirizzo` varchar(60) collate utf8_bin NOT NULL,
PRIMARY KEY (`ospite`,`data`),
KEY `ospite` (`ospite`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
--- Dump dei dati per la tabella `valutazione`
--
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 49 di 80
Progettazione database del sito Frieund.com
Definizione dei vincoli di integrità referenziale
I vincoli d' integrità referenziale sono proprietà che debbono essere soddisfatte dalle istanze della base di dati. Possiamo vederli come predicati che possono assumere un valore booleano e possono agire sulle istanze del DB che sono considerabili corrette se rispettano tutti i vincoli associati. I vincoli definibili possono essere di tipo intra­relazionale e inter­relazionali.
I primi comprendono la primary key, la unique (che prevede l'unicità di un attributo), e i vincoli di tupla tra cui i vincoli di dominio (es: not null). I vincoli inter­relazionali invece legano più tabelle. Quello più usato è sicuramente il vincolo di integrità referenziale dove gli attributi di una data tabella possono assumere soltanto valori specificati in un altra tabella. In SQL tale proprietà è implementabile con il costrutto foreign key (chiave esterna).
Le foreign key
Riportiamo i vincoli relazionali seguendo quanto visto nelle fasi di semplificazione e traduzione del modello logico.
(figura): Le frecce indicano i campi a cui si fa riferimento
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 50 di 80
Progettazione database del sito Frieund.com
Aggiungere le foreign key sulle tabelle esistenti
Nella creazione della tabella possiamo indicare tali vincoli inter­relazionali. Nel nostro caso ciò non è avvenuto, dovremo quindi provvedere al loro inserimento.
tabella valutazione:
ALTER TABLE `valutazione`
ADD CONSTRAINT `val_ospite` FOREIGN KEY (`ospite`)
REFERENCES `utente` (`username`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `val_indirizzo` FOREIGN KEY (`indirizzo`)
REFERENCES `abitazione` (`indirizzo`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `val_proprietario` FOREIGN KEY (`proprietario`)
REFERENCES `abitazione` (`proprietario`)
ON DELETE CASCADE ON UPDATE CASCADE;
tabella abitazione:
ALTER TABLE `abitazione`
ADD CONSTRAINT `ab_proprietario` FOREIGN KEY (`proprietario`)
REFERENCES `utente` (`username`) ON DELETE NO ACTION ON UPDATE CASCADE,
ADD CONSTRAINT `ab_citta` FOREIGN KEY (`nome_citta`)
REFERENCES `citta` (`nome`) ON DELETE CASCADE ON UPDATE CASCADE;
ADD CONSTRAINT `ab_nazione` FOREIGN KEY (`nazione`)
REFERENCES `citta` (`nazione`) ON DELETE CASCADE ON UPDATE CASCADE;
tabella dati_accesso:
ALTER TABLE `dati_accesso`
ADD CONSTRAINT `da_utente` FOREIGN KEY (`username`)
REFERENCES `utente` (`username`) ON DELETE CASCADE ON UPDATE CASCADE;
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 51 di 80
Progettazione database del sito Frieund.com
tabella profilo:
ALTER TABLE `profilo`
ADD CONSTRAINT `profilo_utente` FOREIGN KEY (`utente`)
REFERENCES `utente` (`username`) ON DELETE CASCADE ON UPDATE CASCADE;
tabella piatto:
ALTER TABLE `piatto`
ADD CONSTRAINT `piatto_utente` FOREIGN KEY (`utente`)
REFERENCES `utente` (`username`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `piatto_citta` FOREIGN KEY (`nome_citta`)
REFERENCES `citta` (`nome`) ON DELETE CASCADE ON UPDATE CASCADE;
ADD CONSTRAINT `piatto_nazione` FOREIGN KEY (`nazione`)
REFERENCES `citta` (`nazione`) ON DELETE CASCADE ON UPDATE CASCADE;
tabella utente:
ALTER TABLE `utente`
ADD CONSTRAINT `utente_citta` FOREIGN KEY (`nome_citta`)
REFERENCES `citta` (`nome`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `utente_nazione` FOREIGN KEY (`nazione`)
REFERENCES `citta` (`nazione`) ON DELETE CASCADE ON UPDATE CASCADE;
Nota: Come possiamo notare molti dei riferimenti vanno verso il campo utente.username, tale attributo per scelta non è modificabile né eliminabile. Ogni utente è infatti riconosciuto da tale dato e nessuno può riutilizzare un username di un altro utente (anche se inattivo). Questa scelta progettuale ci evita molte problematiche legate a inconsistenze di vario genere nonché evita ambiguità agli utenti utilizzatori.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 52 di 80
Progettazione database del sito Frieund.com
4.5.2 Definizione delle operazioni
In questa sezione riportiamo il codice SQL utilizzato per le operazioni trattate precedentemente. Visto che nelle applicazioni useremo una sprintf per realizzare la stringa da inviare al RDBMS è lasciato il segnaposto %s come indicatore di variabile (tipo stringa).
Visualizzazione abitazioni presenti in una data città
SELECT proprietario, indirizzo, costo_giorno, numero_posti
FROM abitazione
WHERE nome_citta = '%s' and nazione = '%s'
In base alla scelta potremmo decidere di effettuare un ordinamento per costo o numero posti
aggiungendo la semplice clausola ORDER BY
Visualizzazione valutazioni su una data abitazione
SELECT ospite, data, voto, commento
FROM valutazione
WHERE proprietario = '%s' and indirizzo = '%s'
ORDER BY data DESC
In questo modo visualizzeremo tutte le valutazioni in ordine cronologico inverso dando così maggiore priorità a quelle più recenti
Visualizzazione abitazione di un dato utente proprietario
SELECT *
FROM abitazione
WHERE proprietario = '%s' and indirizzo = '%s'
Inserimento piatto tra ricette
INSERT INTO piatto
values('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
INSERT INTO `Sql180545_1`.`piatto` (`nome`, `lingua`, `categoria`, `ingredienti`, `procedimento`, `nome_citta`, `nazione`, `utente`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'); Visualizzazione piatti di una certa città
SELECT *
FROM piatto
WHERE nome_citta = '%s' and nazione = '%s'
Anche in questo caso nel listing dei risultati potremmo decidere di ordinare i risultati tramite un ORDER BY applicandolo all'attributo piatto.nome
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 53 di 80
Progettazione database del sito Frieund.com
Visualizzazione piatti inseriti da un utente
SELECT *
FROM piatto
WHERE utente = '%s'
ORDER BY nome
Visualizzazione del profilo di un utente
SELECT utente.*, profilo.*
FROM utente JOIN profilo ON (utente.username = profilo.utente)
WHERE utente.username = '%s'
Visualizzazione utenti di una certa città (vedere anche la variante che raffina la ricerca tramite l'età)
SELECT username
FROM utente
WHERE nome_citta = '%s' and nazione = '%s'
ORDER BY username ASC
Aggiornamento del proprio profilo
UPDATE database.profilo
SET messaggio_personale = '%s',
intervista = '%s',
stile = '%s'
WHERE profilo.utente = '%s'
LIMIT 1
Login all'area riservata
SELECT username, privilegio
FROM dati_accesso
WHERE username='%s' and password = '%s'
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 54 di 80
Progettazione database del sito Frieund.com
Visualizzazione di una città di una nazione sulla cartina
SELECT *
FROM citta
WHERE nome='%s' and nazione= '%s'
In realtà tale query è utilizzata dal motore di ricerca per listare le varie città e le operazioni ad esse associate (ricette, utenti, abitazioni, Eu!city). Dati i risultati è scelta l'operazione da compiere su di essa tramite il click su un form che permette di inviare la posizione della città alla pagina php che si occupa di creare l'immagine della cartina.
Iscrizione al sito
Inserimento utente
INSERT INTO utente values(username, nome, sesso, lingua, data_nascita, mail, nome_citta, nazione)
Creazione profilo associato
INSERT INTO profilo values(utente, “new user”, 1023, 1 o 2 in base al sesso, 0 lo stile predefinito)
Inserimento dati di accesso
INSERT INTO dati_accesso values(username, password, 'S')
Per una maggiore chiarezza sono stati riportati in questo caso i nomi dei campi.
'S' forza il privilegio iniziale a quello di utente semplice, sarà poi l'amministratore a poter eventualmente modificarne il valore in seguito. La foto potrà essere presente (0) o assente (1 o 2), nel secondo caso visualizzeremo in base al sesso specificato una diversa immagine alternativa. Per scelta quindi al momento della creazione del profilo è impostata una foto di default che sarà possibile modificare in seguito dal pannello di controllo della propria area personale. Allo stesso modo 0.css rappresenta il foglio di stile predefinito costruito con i colori del sito. Tale valore è comunque modificabile in seguito scegliendo un altro tra i stili proposti e caricati dagli amministratori (locali e totale) nella cartella dedicata.
New user è il messaggio_personale mentre 1023 rappresenta il valore decimale dell'intervista che convertita in binario (bindec(), decbin()) valorizzerà tutte le risposte del profilo appena creato a vero.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 55 di 80
Progettazione database del sito Frieund.com
Per diminuire la complessità delle applicazioni, che trovandosi in un ambiente client/server ne sarebbero molto velocizzate è stato pensato di utilizzare le stored procedures. In particolare per le query più complesse quali la procedura di iscrizione e quella di rimozione dell'utente.
Per invocare la procedura non dovremo far altro che richiamarla e passargli i parametri
Esempio:
mysql_query(sprintf(“CALL iscrizione('%s', '%s', '%s', '%s', '%s', '%s', '%s',
'%s', '%s')”, $username, $nome, $sesso, $lingua, $data_nascita, $mail,
$nome_citta, $nazione, $password));
Iscrizione al sito
create procedure iscrizione (IN username CHAR(30),
IN nome CHAR(30),
IN sesso CHAR(1),
IN lingua CHAR(3),
IN data_nascita CHAR(8),
IN mail CHAR(40),
IN nome_citta CHAR(40),
IN nazione CHAR(3),
IN pwd CHAR(40))
BEGIN
DECLARE foto int;
INSERT INTO utente values(username, nome, sesso, lingua, data_nascita, mail,
nome_citta, nazione);
IF sesso = 'M' THEN SET foto = 1;
ELSE SET foto = '2';
END IF;
INSERT INTO profilo values(username, 'new user', '1023', foto, '0');
INSERT INTO dati_accesso values(username, pwd, 'S');
END //
(usando come separatore il doppio slash)
Ovviamente essendo dichiarato un vincolo di chiave importata sulla città l'inserimento dell'utente sarà bloccato nel caso fosse indicata una città diversa da quelle presenti nella tabella. Nella fase di analisi e progettazione è stato deciso di inserire tutte le città prima del lancio del sito in modo che all'arrivo i vari utenti trovino le varie città inserite. Ciò garantisce consistenza e univocità nella rappresentazione dei vari enti locali e migliora quindi le applicazioni di ricerca e selezione basate su essi. Potremmo altresì definire una versione alternativa che inizialmente ci aiuti nell'inserimento di tale onere in modo che ogni utente in fase di iscrizione controlli se la città indicata esista o meno e in caso negativo provvedere all'inserimento. In tal caso non avremo alcun problema legato ai vincoli di integrità che aggireremo semplicemente.
Tale soluzione può essere utile anche nelle nostre applicazioni presentate in sede di esame dove non si sarà per ovvi motivi provveduto all'inserimento di tutte le città europee.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 56 di 80
Progettazione database del sito Frieund.com
Iscrizione al sito e inserimento citta (per mantenere la consistenza)
CREATE PROCEDURE `iscrizione`(IN username CHAR(30), IN nm CHAR(30), IN sesso
CHAR(1), IN lingua CHAR(3), IN data_nascita CHAR(8), IN mail CHAR(40), IN
nome_citta CHAR(40), IN nation CHAR(3), IN pwd CHAR(40))
BEGIN
DECLARE foto int;
DECLARE esiste int;
SELECT count(*) INTO esiste FROM citta WHERE nome = nome_citta and nazione =
nation;
START TRANSACTION;
IF (esiste = 0) THEN
INSERT INTO citta VALUES(nome_citta, nation, '0', '0');
END IF;
INSERT INTO utente values(username, nm, sesso, lingua, data_nascita, mail,
nome_citta, nation);
IF sesso = 'M' THEN SET foto = 1;
ELSE SET foto = '2';
END IF;
INSERT INTO profilo values(username, 'new user', '1023', foto, '0');
INSERT INTO dati_accesso values(username, pwd, 'S');
COMMIT;
END
questa è la procedura usata nel testing delle nostre applicazioni
Rimozione dal sito
create procedure rimuovi(IN usr CHAR(30))
BEGIN
/* rendo irraggiungibili le abitazioni dell'utente */
UPDATE abitazione
SET
foto
=
'home',
costo_giorno
=
'0',
numero_posti
=
informazioni_aggiuntive = '1023', nome_citta = 'frieund', nazione = 'eu'
WHERE proprietario = usr;
'0',
UPDATE profilo
SET messaggio_personale = 'The user was deleted',
intervista = '1023', /* rimette le risposte al valore di default */
foto = '3',
/* mette a default la foto dell'utente rimosso */
stile = '0'
/* imposta lo stile di default */
WHERE utente = usr;
UPDATE utente
SET nome = 'user deleted',
/* elimina qualsiasi riferimento alla persona */
mail = 'nomail',
/* fa in modo che non gli siano inviabili email */
nome_citta = 'frieund', /* lo toglie dai risultati di ricerca di qualsiasi
città */
WHERE username = usr;
END;
non posso cancellare le abitazioni perchè renderei inconsistente la tabella valutazioni. Per far permanere nel DB tali dati lasciamo proprietario e indirizzo inalterati ma il profilo della abitazione verrà “resettato”.
L'applicazione oltre all'invocazione della procedura si dovrà ovviamente incaricare anche dell'eliminazione delle foto delle abitazioni e del profilo utente.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 57 di 80
Progettazione database del sito Frieund.com
Operazioni aggiuntive
Alcune operazioni, più complesse e spesso usate per ricerche più raffinate sono utilizzate in casi particolari.
Per completezza è stato deciso di riportarle anche se non trattate nell'analisi dei costi.
Visualizzazione abitazioni di una certa città e relativo voto medio SELECT abitazione.proprietario, abitazione.indirizzo, abitazione.costo_giorno,
abitazione.foto, (select avg(voto) from valutazione where valutazione.indirizzo
= abitazione.indirizzo and abitazione.proprietario = valutazione.proprietario)
as voto_medio
FROM abitazione
WHERE abitazione.nome_citta = '%s' and abitazione.nazione = '%s'
Visualizzazione utenti di una città e nazione con una certa età
SELECT utente.username, utente.sesso, profilo.foto
FROM utente JOIN profilo ON utente.username = profilo.utente
WHERE utente.nome_citta = '%s' and utente.nazione = '%s'
year(utente.data_nascita) = year(curdate())-'%d'
and
Visualizzazione piatti di una determinata nazione e categoria
SELECT nome, lingua
FROM piatto
WHERE nome_citta = '%s' and nazione = '%s' and categoria = '%s'
visualizzazione contenuti di un utente (usate nella pagina del profilo utente):
lista viaggi (valutazioni su abitazioni)
SELECT valutazione.data, abitazione.proprietario, abitazione.indirizzo,
abitazione.nome_citta, abitazione.nazione, valutazione.commento,valutazione.voto
FROM valutazione JOIN abitazione ON ((valutazione.proprietario =
abitazione.proprietario) and (valutazione.indirizzo = abitazione.indirizzo))
WHERE valutazione.ospite = '%s'
lista abitazioni
SELECT indirizzo, nome_citta, nazione
FROM abitazione
WHERE proprietario = '%s'
lista piatti (è la stessa che restituisce i piatti di un utente)
SELECT nome, lingua
FROM piatto
WHERE utente = '%s'
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 58 di 80
Progettazione database del sito Frieund.com
Definizione delle transazioni
MySQL è impostato a default per trattare ogni operazione come atomica (caratteristica modificabile cambiando il valore della variabile auto commit). Questo significa che ogni operazione che sottoporremo al DBMS avrà effetti singoli e indipendenti rispetto alle altre.
In alcuni casi però è utile poter sottoporre una serie di operazioni legate tra loro come un unica transazione per fare in modo che l'esito di una influenzi anche la conclusione delle altre poiché una modalità di impiego diversa potrebbe portare ad un inconsistenza nei nostri dati.
MySQL mette a disposizione appositi comandi di inclusione di codice all'interno di un unica operazione atomica, un gruppo di operazioni può quindi essere racchiuso all'interno di tale azione risultando così come atomico.
Nel nostro caso è importante provvedere alla progettazione adeguata delle procedure di iscrizione e rimozione utente, unici casi di gruppi di accessi correlati al DBMS che se non opportunamente trattati potrebbero generare errori nel nostro DB e nelle nostre applicazioni che ne fanno uso.
In particolare ogni utente dovrà avere un suo profilo e suoi dati di accesso, se qualcosa va male nell'inserimento di tali dati, tutte le operazioni coinvolte dovranno essere abortite, i dati quindi non saranno permanenti fino alla segnalazione di commit alla fine della transazione.
Allo stesso modo per la rimozione dell'utente dovremmo poter modificare e/o rimuovere i dati interessati (vedi operazioni) senza poterci permettere di evitare alcuna di queste.
A questo proposito il codice delle nostre procedure può essere racchiuso all'interno dei tag di inizio e fine transazione. Nel momento in cui il DBMS trova tale segnalatore saprà (senza dover necessariamente modificare manualmente la variabile auto commit) della atomicità di tale gruppo di operazioni.
Iscrizione al sito
create procedure iscrizione (IN username CHAR(30), IN nome CHAR(30), IN sesso
CHAR(1), IN lingua CHAR(3), IN data_nascita CHAR(8), IN mail CHAR(40), IN
nome_citta CHAR(40), IN nazione CHAR(3), IN pwd CHAR(40))
BEGIN
DECLARE foto int;
START TRANSACTION;
INSERT INTO utente values(username, nome, sesso, lingua, data_nascita, mail,
nome_citta, nazione);
IF sesso = 'M' THEN SET foto = 1;
ELSE SET foto = '2';
END IF;
INSERT INTO profilo values(username, 'new user', '1023', foto, '0');
INSERT INTO dati_accesso values(username, pwd, 'S');
COMMIT;
END //
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 59 di 80
Progettazione database del sito Frieund.com
Rimozione utente (Set as default settings)
create procedure rimuovi(IN usr CHAR(30))
BEGIN
START TRANSACTION;
UPDATE abitazione
SET foto = 'home', costo_giorno = '0', numero_posti = '0',
informazioni_aggiuntive = '1023', nome_citta = 'frieund', nazione = 'eu'
WHERE proprietario = usr;
UPDATE profilo
SET messaggio_personale = 'The user was deleted', intervista = '1023', foto =
'3', stile = '0'
WHERE utente = usr;
UPDATE utente
SET nome = 'user deleted',mail = 'nomail', nome_citta = 'frieund'
WHERE username = usr;
COMMIT;
END
Per poter utilizzare questa funzionalità è però necessario utilizzare uno storage engine transazionale, in caso contrario i nostri utili accorgimenti saranno ignorati.
Questo argomento sarà affrontato meglio in fase di progettazione fisica. ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 60 di 80
Progettazione database del sito Frieund.com
5. Progettazione fisica
La progettazione fisica di una base di dati riceve in ingresso lo schema relazionale della realtà di interesse e si occupa di adattarlo al DBMS e alla piattaforma software a disposizione.
La progettazione fisica tenta di ottimizzare la struttura di memorizzazione dei dati in modo che le operazioni di accesso risultino efficienti. Essa deve essere guidata quindi dalla natura dei nostri dati e dall'uso che è stato pensato per essi. Tale fase può essere suddivisa in più passi, la prima di adattamento dello schema logico al DBMS prescelto in cui si acquisiscono conoscenze sulle funzionalità messe a disposizione. Nel secondo passo si analizzano le transazioni insieme alla frequenza di attivazione; da esse sono identificate le porzioni del DB che potrebbero causare problemi di performance.
In particolare sono osservati gli attributi maggiormente colpiti dalle nostre operazioni e ciò ci sarà utile per la scelta dell'organizzazione dei dati e l'eventuale uso di indici.
La versione di MySQL su cui costruiremo la nostra base di dati è la 5.0.68 ­log, i motori a nostra disposizione sono MyISAM, MEMORY e MRG_MyISAM.
La mancanza di InnoDB ci preclude il supporto transazionale e l'utilizzo delle foreign key e dell'integrità referenziale tra tabelle cui saremo costretti a provvedere in applicazioni più complesse.
MyISAM mette a disposizione organizzazioni di tipo B­tree cosi come MRG­MyISAM. MEMORY permette la scelta tra entrambe le soluzioni utilizzando a default organizzazioni di tipo hash. Queste risultano utili nel momento in cui è necessario individuare tuple che hanno un attributo a valore univoco e sono quindi utilizzabili solo per confronti che includono l'operatore di uguaglianza , i B­tree invece sono consigliati per le operazioni di individuazione di tuple il cui attributo è compreso in un range di valori. La progettazione fisica deve fare in modo che la gestione effettiva dei dati sia efficiente, se in una operazione vogliamo ad esempio le ricette ordinate per nome è una buona scelta ordinare il file in base all'attributo nome.
Abbiamo scelto la modalità di organizzazione del nostro file. Il compito del passo successivo è quello della discussione di un eventuale utilizzo di indici, strutture ausiliare associate alla nostra base di dati che possono essere utilizzate per evitare di scorrere il file in modo sequenziale ogni volta che vogliamo ritrovare un informazione. Essi possono quindi migliorare decisamente le performance a discapito di un utilizzo di memoria maggiore dovuto al mantenimento del servizio. Ovviamente abbiamo necessità di mantenere aggiornato l'indice è ogni modifica dei dati dovrà provocare una modifica in tale supporto, e ciò è un costo aggiuntivo se si decide di utilizzarne.
Partiamo innanzitutto dal calcolo del caso pessimo per ogni schema di relazione, lo scorrimento di ogni tupla in modo sequenziale.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 61 di 80
Progettazione database del sito Frieund.com
Dimensione dei file e costo di accesso sequenziale
Ponendo che:
Un blocco in mysql è grande 1K cioè 1024 byte
NP = numero pagine = dimensione blocco * numero tuple * dimensione tuple
NP * dimblocco = numero tuple * dimensione tuple
Calcoliamo il costo di accesso sequenziale ai nostri schemi di relazione semplicemente calcolando il numero di pagine associate.
citta(nome, nazione, posx, posy)
varchar(40) + char(3) + unsigned smallint(4) + unsigned smallint(4)
(40+1) + 3 + (4*2) + (4*2) = 44 + 16 = 60 byte = DR
NP = (80000*60) / 1024 = 4.687,5
dati_accesso(username, password, privilegio)
varchar(30) + char(40) + enum
(30+1) + 40 + 1 = 72 byte = DR
NP = (1.000.000 * 72) / 1024 = 70.312,5
utente(username, nome, sesso, lingua, data_nascita, mail, nome_citta, nazione)
varchar(30) + varchar(30) + enum + char(3) + date + varchar(40) + varchar(40) + char(3)
(30+1) + (30+1) + 1 + 3 + 3 + (40+1) + (40+1) + 3 = 62 + 10 + 82 = 154 byte = DR
NP = (1.000.000 * 154) / 1024 = 150.390,625
piatto(nome, lingua, categoria, procedimento, ingredienti, nome_citta, nazione, utente)
varchar(40) + char(3) + enum + text + text + varchar(40) +char(3) +varchar(30)
(40+1) + 3 + 1 + (2+n) + (2+n) + (40+1) + 3 + (30+1) = DR
nelle applicazioni abbiamo deciso di permettere al massimo 300 caratteri per gli ingredienti e 600 per il procedimento. Sostituendo abbiamo 1024 byte nel caso pessimo.
NP = (5000*1024)/1024 = 5000
profilo(utente, messaggio_personale, intervista, foto, stile)
varchar(30) + text + unsigned smallint(4) + unsigned smallint(1) + unsigned tinyint(2)
(30+1) + (n+2) + (4*2) + (2*1) + 2 = 31 + (n+2) + 12 = 45 + n Per scelta abbiamo vincolato il campo messaggio alla dimensione di un SMS (160 char)
il totale in questo caso è 45 + 160 = 205 byte = DR
NP = (1.000.000 * 205) / 1024 = 200.195,3125
valutazione(ospite, data, voto, commento, proprietario, indirizzo)
varchar(30) + date + unsigned tinyint(2) + text + varchar(30) + varchar(60)
(30+1) + 3 + 2 + (n+2) + (30+1) + (60+1) = 120 + 10 + n = 130 + n
Se n = 160, 130 + 160 = 290 byte = DR
NP = (40.000 * 290) / 1024 = 11.328,125
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 62 di 80
Progettazione database del sito Frieund.com
abitazione(proprietario, indirizzo, costo_giorno, numero_posti, informazioni_aggiuntive, nome_citta, nazione)
varchar(30) + varchar(60) + char(14) + unsigned smallint(3) + unsigned tinyint(2) + unsigned smallint(4) + varchar(40) + char(3)
(30+1) + (60+1) + 14 + (2*3) + 2 + (4*2) + (40+1) + 3 = 19 + 92 + 55 = 166 byte = DR
NP = (10.000 * 166) / 1024 = 1.621,09375
Ora abbiamo il costo di accesso nella situazione peggiore.
Analizzando le nostre operazioni (escluse quelle di inserimento) potremo capire se in qualche modo sarà possibile migliorarne le performance.
Visualizzazione abitazioni presenti in una data città
SELECT proprietario, indirizzo, costo_giorno,
numero_posti
FROM abitazione
WHERE nome_citta = '%s' and nazione = '%s'
Visualizzazione valutazioni su una data abitazione
SELECT ospite, data, voto, commento
FROM valutazione
WHERE proprietario = '%s' and indirizzo = '%s'
ORDER BY data DESC
Visualizzazione abitazione di un dato utente proprietario
SELECT *
FROM abitazione
WHERE proprietario = '%s' and indirizzo = '%s'
Visualizzazione dei piatti di una determinata città
SELECT *
FROM piatto
WHERE nome_citta = '%s' and nazione = '%s'
ORDER BY piatto.nome
Visualizzazione dei piatti inseriti da un utente
SELECT *
FROM piatto
WHERE utente = '%s'
ORDER BY nome
ANDREA MONACCHI ­ A.A. 2008/2009
R
87.108 / day
Chiave primaria tabella:
proprietario, indirizzo
R
73.170 / day
Chiave primaria tabella:
ospite, data
R
104.529 / day
Chiave primaria tabella:
proprietario, indirizzo
R
52.264,8 / day
Chiave primaria tabella:
nome, lingua
R
52.264,8 / day
Chiave primaria tabella:
nome, lingua
Pagina 63 di 80
Progettazione database del sito Frieund.com
Visualizzazione utenti di una determinata città
SELECT username
FROM utente
WHERE nome_citta = '%s' and nazione = '%s'
ORDER BY username ASC
Login all'area riservata
SELECT username, privilegio
FROM dati_accesso
WHERE username='%s' and password = '%s'
Visualizzazione del profilo di un utente
SELECT utente.*, profilo.*
FROM utente JOIN profilo ON (utente.username =
profilo.utente)
WHERE utente.username = '%s'
Disattivazione di un utente dal sito
R
209.059,2 / day
Chiave primaria tabella:
username
R
580.720 / day
Chiave primaria tabella:
username
R
1.742.160 / day
Chiave primaria:
utente.username
profilo.utente
W
0,58 / day
UPDATE abitazione
SET foto = 'home',
costo_giorno = '0',
numero_posti = '0',
informazioni_aggiuntive = '1023',
nome_citta = 'frieund',
nazione = 'eu'
WHERE proprietario = usr;
UPDATE profilo
SET messaggio_personale = 'The user was deleted',
intervista = '1023',
foto = '3',
stile = '0'
WHERE utente = usr;
UPDATE utente
SET nome = 'user deleted',mail = 'nomail', nome_citta = 'frieund'
WHERE username = usr;
Visualizzazione di una città di una nazione sulla cartina
R
348.432 / day
SELECT *
FROM citta
WHERE nome='%s' and nazione= '%s'
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 64 di 80
Progettazione database del sito Frieund.com
Criteri di scelta degli indici
Costruiamo una lista di attributi candidati su cui saranno costruiti indici. ➢
➢
➢
➢
Indicizzare la chiave primaria di ogni relazione Aggiungere un indice secondario per gli attributi frequentemente coinvolti da operazioni di selezione e join, ordinamento e raggruppamento
Non indicizzare tabelle troppo piccole dove il costo aggiuntivo dell'indice risulta inutile né quelle in cui le interrogazioni restituiscono un numero significativo di tuple e l'utilizzo dell'indice non migliora l'accesso ai dati rispetto alla scansione sequenziale
Non indicizzare attributi che consistono in lunghe stringhe di caratteri né attributi legati da clausole OR in criteri di ricerca (gli indici risultano inutili in quanto sarà comunque necessaria una ricerca sequenziale)
Procediamo a costruire la nostra lista di indici candidati tenendo conto delle operazioni riportate precedentemente
Schema di relazione
Indice primario
Indice secondario
dati_accesso
username
/
Utente
username
nome_citta, nazione
Abitazione
Proprietario, indirizzo
nome_citta, nazione
Piatto
Nome, lingua
Profilo
username
/
Valutazione
Ospite, data
Proprietario, indirizzo
Citta
Nome, nazione
/
a) nome_citta, nazione
b) utente
Nell'ipotesi di poter usufruire di qualsiasi tipo di organizzazione nel nostro DBMS opteremmo per organizzazioni primarie di tipo hash che soprattutto nella ricerca dell'username (login e visualizzazione profili) migliorerebbe decisamente le performance di accesso. ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 65 di 80
Progettazione database del sito Frieund.com
Rimozione degli indici candidati troppo costosi
Il mantenimento dell'indice potrebbe gravare sulle operazioni di aggiornamento, è quindi bene valutare se rimuoverlo dalla lista creata. Alcuni DBMS consentono agli utenti di valutare l'esecuzione ripetuta delle query in un vero e proprio banco di prova o di assistere alle strategie intraprese dall'ottimizzatore durante l'esecuzione di una query, in particolare MySql permette l'utilizzo dello strumento benchmark e del prefisso explain che permette di “spiegare” l'interrogazione. Tale funzionalità può essere usata anche nel caso si riscontri una certa lentezza nell'esecuzione.
Prima di procedere alla analisi vera e propria ricapitoliamo le leggi valide nei nostri calcoli di accesso
Tipo accesso
Costo
Scansione sequenziale
NPr
Ricerca binaria
log2 NPr [ + ⎡fp(A) ⋅ NPr⎤ ]
Accesso con indice clustered
(hA – 1) + ⎡fp(A) ⋅ NLA⎤ + ⎡fp(A) ⋅ NPr⎤
Accesso con indice unclustered
(hA – 1) + ⎡fp(A) ⋅ NLA⎤ + ⎡Φ(fp(A) ⋅ NTr, NPr)⎤
Accesso hashed
Costo = 1 + [fattore che dipende dall’hashing]
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 66 di 80
Progettazione database del sito Frieund.com
Progettazione fisica utilizzando InnoDB
Nel caso ottimo, avremo comunque bisogno di un supporto transazionale, caratteristica che come abbiamo visto solo InnoDB ci mette per ora a disposizione (tra i motori affrontati).
Visto che esso indicizza automaticamente le chiavi primarie e le chiavi importate possiamo decidere di evitare l'analisi per tali accessi.
Visualizzazione abitazioni presenti in una data città: criterio di ricerca sulla chiave importata
Visualizzazione valutazioni su una data abitazione: criterio di ricerca agisce sulla chiave importata
Visualizzazione abitazione di un dato utente proprietario: il criterio di ricerca agisce sulla chiave primaria
Visualizzazione dei piatti di una determinata città: il criterio di ricerca agisce sulla chiave importata
Visualizzazione piatti inseriti da un utente: il criterio di ricerca agisce sulla chiave importata
Visualizzazione utenti di una determinata città: il criterio di ricerca agisce sulla chiave importata
Login all'area riservata: il criterio di ricerca agisce sulla chiave primaria e sul campo password
Visualizzazione del profilo di un utente: operazione di join più frequente ma agisce sulle chiavi primarie delle tabelle
Rimozione utente dal sito: poco frequente e agisce sul campo username che è indicizzato o PK
Visualizzazione di una città di una nazione sulla cartina: citta e nazione sono le chiavi primarie
Le operazioni più importanti viste in fase di ottimizzazione sono esenti da accessi su campi diversi da quelli già indicizzati. Questo significa che su di essi non dovremo operare ulteriormente con i mezzi a nostra disposizione. (Se avessimo avuto la disponibilità delle org. Hash in certi casi avremmo sicuramente saputo abbassare i costi)
Gli unici casi in cui potremmo pensare di migliorare il piano di accesso sono le query meno frequenti che abbiamo aggiunto come esercizio e come applicazioni di maggior raffinamento della selezione ovvero come ausilio ed estensione delle operazioni principali.
visualizzazione abitazioni di una certa città e relativo voto medio: agisce sulle chiavi primarie e importate (proprietario, indirizzo e nome_citta, nazione)
visualizzazione utenti di una città e nazione con una certa età: il predicato di ricerca agisce sull'username (PrimaryKey) e sulla città e nazione (ForeignKey) e sulla data di nascita (anno)
visualizzazione piatti di una determinata città e nazione e categoria: città e nazione sono chiavi importate mentre il campo categoria risulta non indicizzato.
Lista piatti: già trattata come visualizzazione piatti di un utente.
Lista viaggi (valutazioni): agisce su parte della primarykey ovvero ospite invece che ospite, data
lista abitazioni: agisce su proprietario invece che su proprietario, indirizzo
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 67 di 80
Progettazione database del sito Frieund.com
Questo porta ad una nuova tabella di indici candidati visto che quella vecchia è stata già indicizzata automaticamente dal DBMS.
operazione
campo
Tipo indice
Visualizzazione utenti di una città e nazione con una certa età
Utente.data_nascita
Secondary unclustered
Visualizzazione piatti di una città e nazione di una determinata categoria
Piatto.categoria
Secondary unclustered
Valutazione.ospite
Secondary unclustered
Abitazione.proprietario
Secondary unclustered
Lista viaggi (valutazioni)
Lista abitazioni
Visto che la visualizzazione del profilo di un utente è l'operazione più costosa e frequente di tutto l'applicativo web, le operazioni di listing dei viaggi e delle abitazioni che sono legate ad esso saranno quelle su cui dovremo puntare maggiormente in quanto sebbene secondarie saranno comunque attivate dalla pagina più vista e quindi transitivamente anche esse avranno una frequenza rilevante.
Lista viaggi
NT = 40.000
NP = 11.329
NK: 50.000 ospiti ma solo 8 su 10 lasciano valutazioni e quindi le 40.000 valutazioni sono in media ogniuna di un utente. f = 1/40.000
Ospite è un campo varchar(30) quindi nel caso pessimo occuperà 31 byte
NL = NR∗len pNK ∗len k 
= D∗u
= 1981,43
costo accesso = (hA – 1) + ⎡fp(A) ⋅ NLA⎤ + ⎡Φ(fp(A) ⋅ NTr, Npr)⎤ = 5 + 1 + 1 = 7
lista abitazioni
NT = 10.000
NP = 1621
NK = 10.000 proprietari ogniuno con una abitazione
NR∗len pNK ∗len k 
NL =
= D∗u
= 495,357
costo accesso = (hA – 1) + ⎡fp(A) ⋅ NLA⎤ + ⎡Φ(fp(A) ⋅ NTr, Npr)⎤ = 4 + 1 + 1 = 6
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 68 di 80
Progettazione database del sito Frieund.com
Ottimizzazione
L'ottimizzatore del DBMS valuterà se effettuare un accesso sequenziale o utilizzare gli indici preposti, nel caso le tuple siano un numero molto minore di quello dichiarato infatti esso ne eviterà l'utilizzo. Dimostriamolo verificando i tempi di accesso sulle relazioni prima e dopo dell'indice, a parità di tuple.
Lista viaggi utente
riportiamo l'explain dei viaggi dell'utente tester
id select_type
Table
Type possible_keys
1
SIMPLE
Valutazione
ref
1
SIMPLE
Abitazione eq_ref
key
key_len
ref
rows
extra
PRIMARY, PRIMARY
proprietario
92
const
2
Using where
PRIMARY
274
Valutazione.proprietario valutazione.indirizzo
1
PRIMARY
vediamone le performance ripetendo la query 100.000.000 di volte per valutare meglio i tempi
Tempo: tentativo 1 – 0,8132 secondi
tentativo 2 – 0,8059 secondi
tentativo 3 – 0,8051 secondi
ora creiamo l'indice su ospite riportando i tempi
tempo: tentativo 1: 0,8060 secondi
tentativo 2: 0,8079 secondi
tentativo 3: 0,8048 secondi
e ne vediamo nuovamente le scelte di esecuzione notando come la situazione non sia cambiata (poche tuple)
id select_type
Table
Type possible_keys
1
SIMPLE
Valutazione
ref
1
SIMPLE
Abitazione eq_ref
key
key_len
ref
rows
extra
PRIMARY, proprietario, PRIMARY
ospite
92
const
2
Using where
PRIMARY
274
Valutazione.proprietario valutazione.indirizzo
1
PRIMARY
Lista abitazioni utente
Vediamo le performance eseguendo la query sulle abitazioni dell'utente local (20 tuple)
id
select_type
Table
Type
possible_keys
key
key_len
ref
rows
extra
1
SIMPLE
abitazione
ref
PRIMARY
PRIMARY
92
const
20
Using where
Ripetendo la query 100.000.000 di volte tramite il comando benchmark otteniamo
tentativo 1: 0,8065 secondi
tentativo 2: 0,8051 secondi
tentativo 3: 0,8130 secondi
inserendo l'indice sull'attributo proprietario vediamo come esso sia subito utilizzato dal DBMS
id
select_type
Table
Type
possible_keys
key
key_len
ref
rows
extra
1
SIMPLE
abitazione
ref
PRIMARY, proprietario
proprietario
92
const
20
Using where
Tempi di accesso: tentativo 1: 0,81 secondi
tentativo 2: 0,8096 secondi
tentativo 3: 0,8059 secondi
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 69 di 80
Progettazione database del sito Frieund.com
Progettazione fisica usando motori alternativi
Quando non è possibile usare InnoDB, come nel nostro caso, è necessario poter prevedere valide alternative insieme a soluzioni che ne permettano un uso adatto alle applicazioni che ne andranno a fare uso.
MEMORY
La prima alternativa presentata è lo storage engine memory (conosciuta anche come heap), le cui tabelle sono conservate in memoria centrale (volatile), ciò garantisce altissima velocità in quanto si evitano gli accessi al disco ma non garantisce consistenza e durabilità dei dati che vedremo persi alla chiusura della sessione. Al restart del server avremo così tabelle vuote. Le tabelle memory non sono mai convertite in tabelle su disco. L'unica memorizzazione è effettuata per la struttura della tabella che risiede sul file system in un file con estensione .frm.
Memory nasce principalmente per sopperire all'assenza di una tipologia di tabelle temporanee in mysql.
L'unica soluzione utilizzabile può essere quella del caricamento delle tuple nella fase di avvio da un file di testo che permetta ad ogni chiusura di poter memorizzare in modo stabile lo stato del database. Ciò può avvenire ad opera di un comando INSERT (vedi anche prepared statement php) o di un LOAD DATA INFILE.
Vantaggi:
Alta velocità di risposta. Uso di organizzazioni hash in modo molto elastico (è possibile indicizzare anche campi a valori non unici e null cosi come utilizzare campi autoincrement)
Limitazioni:
Le tabelle usano un formato a lunghezza fissa e quindi tipi come varchar non permettono risparmio di memoria rispetto ai char.
I tipi BLOB e TEXT non sono supportati.
Ogni tabella può avere al massimo 32 indici, ognuno composto al massimo di 16 colonne e di massimo 500k per riga.
La dimensione massima di una tabella è settata a default a 16 MB (ma comunque modificabile con un set) nella variabile di sistema max_heap_table_size.
L'eliminazione di tuple non garantisce la disallocazione dello spazio dedicato ad esse; ciò significa che si continuerà ad avere una tabella di stessa dimensione in memoria che sarà liberabile con un istruzione truncate table o eliminando e ricreando la tabella.
Progettazione fisica
L'unica caratteristica che potrebbe farci scegliere questo tipo di motore è sicuramente il supporto per le organizzazioni di tipo hash. In particolare le tabelle come dati_accesso, utente e profilo hanno associate operazioni molto frequenti che fanno capo al campo username. Le limitazioni viste però non sono trascurabili, il caricamento di 1.000.000 di tuple per ogniuna di queste tabelle può diventare un limite, oltre al fatto che il campo messaggio_personale è un txt e non sarebbe implementabile se non con un char da 160 caratteri. L'inaffidabilità e la necessità di possedere un file di testo con migliaia di tuple ci ha spinto ad abbandonare anche solo l'ipotesi di un implementazione di tabelle di questo genere. L'utilità potrebbe essere nel caso di script come ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 70 di 80
Progettazione database del sito Frieund.com
“numero utenti on line” o semplici chat che non hanno necessità di affidabilità ne di memorizzazione e la velocità di tale supporto lo rende la più valida alternativa al semplice file di testo.
MyISAM
MyIsam è un motore non transazionale che si trova in modo predefinito sulle attuali versioni di mysql. Esso deriva dalla struttura ISAM da cui prende anche parte del nome. É molto veloce e il limite principale è il mancato supporto alle transazioni.
Ogni tabella di questo tipo è memorizzata in 3 file distinti, uno .frm che ne descrive la struttura, uno .MYI che contiene gli indici e uno di tipo MYD che contiene i dati veri e propri.
Le tabelle di tipo MyISAM dal punto di vista dell'implementazione da comando SQL è analoga a quella delle tabelle InnoDB. Possiamo usare gli stessi comandi, semplicemente le funzioni aggiuntive introdotte da InnoDB come le transazioni e le foreign key saranno ignorate. Questo significa che possiamo riutilizzare gli indici calcolati per gli schemi di relazione InnoDB ma dovremo inserire manualmente quelli sulle chiavi importate in quanto MyISAM non lo fa automaticamente.
Le buone caratteristiche prestazionali ci hanno fatto optare per questa valida alternativa nella realizzazione delle nostre tabelle. Una soluzione che non ci garantirà la consistenza dei nostri dati se non da applicazioni più sicure e pesanti.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 71 di 80
Progettazione database del sito Frieund.com
6. Implementazione interfaccia
Come introdotto inizialmente, la base di dati dovrà poter essere fruibile da un sito web. Il linguaggio server side scelto è php, open source e con sintassi C­like, ci permetterà di scrivere applicazioni complesse in modo semplice e veloce. In molte parti si fa uso anche della tecnologia AJAX cioè dell'uso di javascript per il recupero di pagine evitando del reload della pagina.
6.1 descrizione applicazione
Evitando di introdurre codice sorgente in questa relazione, il cui scopo è sicuramente diverso, rimandiamo al sito vero e proprio dove potranno essere provate le operazioni considerate.
Non troveremo una pagina contenente le varie query ma un sito pronto all'uso. Per alcune operazioni come il login o l'inserimento ricette sarà quindi necessario sostenere la procedura di iscrizione (in caso la si voglia saltare si forniscono le credenziali di testing, User: tester, Pass: tester che ha privilegi di utente semplice, per accedere come local o admin contattare l'amministratore di sistema)
Digitando come URL http://www.frieund.com troveremo una pagina del tipo:
Tale applicazioni sono state testate con esito positivo su un browser Google Chrome, sia il template che il foglio di style sono stati validati con successo dagli standard W3C.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 72 di 80
Progettazione database del sito Frieund.com
Riportiamo alcune delle operazioni per guidare il visitatore nella sua prima esperienza on line.
Iscrizione al sito:
login all'area riservata: visualizzazione del profilo di un utente: all'interno di tale applicazione è possibile richiamare le query:
visualizza piatti di un dato utente, visualizza abitazioni di un utente, visualizza viaggi di un utente che listeranno il loro risultato in un div nascosto da cui sarà possibile puntare alla visualizzazione specifica e completa del singolo risultato selezionato.
In particolare: visualizza abitazione (pagina profilo) di un dato utente proprietario
visualizza abitazione (pagina profilo) di un dato utente ospite
visualizza piatto
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 73 di 80
Progettazione database del sito Frieund.com
aggiornamento del proprio profilo
aggiornamento dei propri dati e possibilità di rimozione dell'utente:
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 74 di 80
Progettazione database del sito Frieund.com
visualizzazione abitazioni di una certa città e relativo voto medio: visualizzazione utenti di una città e nazione con una certa età: visualizzazione piatti di una determinata città e nazione e categoria: ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 75 di 80
Progettazione database del sito Frieund.com
7. Appendice
In questa sezione trovano spazio gli argomenti di supporto alla nostra progettazione che non hanno avuto spazio durante le fasi di analisi e implementazione.
Esempio di connessione ad un database MySql tramite le API funzionali di PHP
Riportiamo un frammento di codice sorgente della pagina view.php incaricata della visualizzazione del profilo di un utente
<?php // apro la connessione dal database
require_once($_SERVER['DOCUMENT_ROOT'].'xyz.php');
// seleziono il database
$db = @mysql_select_db("Sql180545_1", // nome del database
$connessione) // nome della connessione
or die ("Impossible to select database.");
// eseguo la query
$result = @mysql_query(sprintf("SELECT * FROM utente JOIN profilo ON utente.username =
profilo.utente WHERE utente.username = '%s'", $_POST['user']));
// controllo che esista almeno un record
if(mysql_num_rows($result) > 0)
{
// prelevo una riga della tabella risultante come array associativo
$riga = mysql_fetch_assoc($result);
}
else
{
// l'utente non è stato trovato
$messaggio = "The user <strong>".$_POST['user']."</strong> cannot be loaded";
}
// chiudo la connessione con il database
mysql_close($connessione);
?>
in questo caso il risultato dovrebbe essere una sola tupla e per accedere ai suoi valori ci basta la notazione $riga['nome_campo'] essendo stato richiesto un array associativo.
Note: ­ xyz.php è un file contentente la stringa di connessione al DB:
// connessione al database frieund
$connessione = @mysql_connect("62.149.150.72", // server database
"", // username
"") // password
or die ("impossibile instaurare una connessione");
@ è l'operatore silence che evita la visualizzazione di errori del DBMS che potrebbero far trapelare ad utenti non autorizzati eventuali bug o caratteristiche del sistema.
I tipi di connessione al DBMS in php sono principalmente due quella persistente e quella non ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 76 di 80
Progettazione database del sito Frieund.com
persistente, nel nostro caso come intuitibile è stata utilizzata la connessione non persistente, che è chiusa dalla funzione mysql_close al termine della query (sarebbe stata comunque chiusa al termine dello script)
Estensione mysqli (improved)
Con l'avvento della versione 5 di php è stata inclusa una nuova estensione per l'accesso ai database mysql, MySQLi. Tale strumento è stato introdotto per supportare le nuove API Client MySQL 4.1 e 5.0 che hanno introdotto nuove funzionalità. Tali strumenti sono fruibili con un interfaccia di gestione ad oggetti che ricalca molto (anche mnemonicamente) quella procedurale precedente. Molte delle funzioni utilizzate precedentemente infatti sono riportate e modificate dal semplice inserimento di una i (improved).
Riportiamo per una maggiore comprensione una connessione al DBMS
<?php
$connessione = mysqli_connect(“localhost”, // host name
“”, // username
“”, // password
“”); // database name
// se la connessione fallisce la connect restituisce FALSE
if(empty($connessione)) {
die(“Connessione non riuscita”.mysqli_connect_error());
}
?>
Ora siamo connessi al nostro DBMS. Potremmo voler effettuare un interrogazione
<?php
$risultato = $connessione->query(“Query SQL”);
while($riga = $risultato->fetch_row()) {
print $riga[0].”\n”;
}
$risultato->free();
$connessione->close();
?>
Come per l'estensione mysql abbiamo tre sistemi diversi di recupero record dai risultati, un array numerato, un array associativo oppure come oggetto. (fetch_row(), fetch_assoc(), fetch_object())
Nota:
L'estensione MySQLi consente anche di inviare dichiarazioni SQL multiple in un unica chiamata di funzione separando le varie stringhe da un punto e virgola. Il recupero dei set di risultati dalle dichiarazioni multiple risulterà ovviamente più complesso.
Quanto visto risulta molto simile a quanto fatto nel caso dell'estensione mysql. Uno dei vantaggi offerti dall'estensione mysqli rispetto ad essa è la possibilità di utilizzare le prepared statement ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 77 di 80
Progettazione database del sito Frieund.com
(dichiarazioni preparate) che permettono agli sviluppatori di realizzare query più sicure e prestazioni migliori. È necessario creare un modello di query e inviarlo al server MySQL, esso ne controllerà la validità per garantirne il funzionamento e lo acquisirà. Al client restituirà un puntatore che potrà in seguito essere usato come riferimento alla dichiarazione preparata.
Le variabili implicate nella query saranno di due tipi: input (collegate alla dichiarazioni) o output (collegate al set di risultati). Il segnaposto utilizzato al posto dei valori reali è il punto interrogativo.
Esempio: inserimento di un piatto tra le ricette
<?php
// mi connetto al DBMS
$connessione = mysqli_connect(“”, ””, “”, “”);
// creo la prepared statement
$dichiarazione = $connessione­>prepare(“INSERT INTO ricette VALUES(?, ?, ?, ?, ?, ?, ?, ?)”);
// collego le variabili di input
$dichiarazione­>bind_param($nome, $lingua, $categoria, $ingredienti, $procedimento, nome_citta, nazione, utente);
// ora inserisco le tuple
$nome = 'piadina';
$lingua = 'I';
$categoria = 'P';
$ingredienti = 'acqua, sale,....';
$procedimento = 'prendere.....';
$nome_citta = 'urbino';
$nazione = 'I';
$utente = 'tester';
$dichiarazione­>execute();
$nome = 'torta paradiso';
$lingua = 'I';
$categoria = 'D';
$ingredienti = 'latte, farina,....';
$procedimento = 'prendere.....';
$nome_citta = 'roma';
$nazione = 'I';
$utente = 'tester';
$dichiarazione­>execute();
?>
Tale sistema può risultare utile nel caso si debbano inserire un gran numero di dati come ad esempio il momento della popolazione del DB.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 78 di 80
Progettazione database del sito Frieund.com
Sicurezza
Riportiamo in questa breve sezione alcuni dei parametri utilizzati per garantire una sicurezza dei dati memorizzati nella nostra base di dati e delle applicazioni che ne fanno uso ad eventuali accessi non autorizzati.
SQL_INJECTION (query injection)
La funzioni addslashes è in disuso mentre mysql_escape_string è stata deprecata. Al loro posto si applica la funzione mysql_real_escape_string() che permette di risolvere il problema delle query injection con l'escaping dei caratteri speciali di sql. VARIABLE INJECTION
Per evitare questo problema è stato deciso di non utilizzare variabili GET né COOKIE, il passaggio di valori avviene tramite l'array globale POST e l'autenticazione è gestita con il meccanismo delle sessioni cui è stato espressamente indicato di non usare in nessun caso cookie. Le variabili POST non sono mai recuperate dall'array $_REQUEST e su di esse sono effettuati controlli di esistenza e consistenza nonché in determinati casi il casting forzato.
XSS (Cross Site Script)
Per risolvere il problema dell'inclusione di codice malevolo è stato pensato di filtrare i dati immessi nei nostri campi.
strip_tags(stringa) si occupa di eliminare eventuali tag html e php presenti
htmlentities(stringa) converte caratteri speciali in testo html
L'utilizzo congiunto di queste due funzioni ci permettono una protezione sufficiente a tale problematica
Password
Per la protezione delle password è stato deciso l'utilizzo della funzione hash sha­1.
La lunghezza di tale campo è stata vincolata tra 8 e 14 caratteri per garantire una sicurezza minima.
Visibilità dei parametri di connessione al DBMS
Il file contenente i parametri di connessione, nonché la password in chiaro è stato memorizzato in una cartella protetta da lettura e scrittura.
Accesso al DBMS
Per la connessione al DBMS è preferibile accedere da un utente non amministratore in modo da poterne limitare i privilegi. Un utente è creabile e gestibile tramite la sintassi GRANT di MySql.
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 79 di 80
Progettazione database del sito Frieund.com
8. Bibliografia
Riportiamo le fonti che abbiamo consultato nella realizzazione del nostro elaborato.
Leonardo Bellini, “Fare business con il web, scacco alla rete in 7 mosse”, Lupetti 2006
Azteni, Ceri, Paraboschi, Torlone, “Basi di dati, modelli e linguaggi di interrogazione”, McGraw Hill, 2002
Rasmus Lerdorf, “PHP Pocket Reference”, O'Reilly 1999
Andi Gutmans, Stig S. Bakken, Derick Rethans, “PHP 5 guida completa”, APOGEO 2005
Kevin Yank, “PHP e MySQL creare siti web”, Mondadori informatica 2005
Sitografia
http://www.php.net
http://www.mysql.it
ANDREA MONACCHI ­ A.A. 2008/2009
Pagina 80 di 80