Dispense - Istituto Angioy Carbonia, Corso di Informatica, prof

Istituto “Angioy”
Informatica
BASI DI DATI
Prof. Ciaschetti
Introduzione e prime definizioni
Una Base di dati o Database è un archivio elettronico opportunamente organizzato per reperire in
modo efficiente le informazioni ivi memorizzate. Come tutti gli archivi elettronici, un database è
realizzato tramite uno o più file, memorizzati in modo permanente. A differenza degli archivi
tradizionali su file di testo o file binari (si veda la dispensa su Archivi e File), un database è un file
strutturato in modo tale da consentire l‟accesso e la gestione dei dati a un particolare software, il
Gestore del database, (Data Base Management System, DBMS).
ESEMPI DI DBMS
DB2
ORACLE
MS ACCESS
MS SQL SERVER
MySQL
dBase
SQL Anywhere
Base
creato da Informix, (poi acquisita da IBM), è uno dei DMBS più diffusi sul
mercato.
insieme al DB2, è la regina del mercato dei DMBS: si tratta di un prodotto
altamente professionale e molto costoso, il migliore in termini di
robustezza, sicurezza e affidabilità.
è il DBMS di Microsoft Office per utenti domestici; possiede una comoda
interfaccia grafica per utilizzarlo.
versione professionale di Access.
è il più diffuso DBMS open source, per via della sua versatilità, facilità
d‟uso ed economicità
è il più antico DBMS, poi evoluto in versioni più aggiornate (dBaseII,
dBaseIII e dBaseIV)
creato da Sybase, una delle maggiori società al mondo produttrici di DBMS.
versione open source e gratuita del famoso Access di Office. Si trova nel
pacchetto OpenOffice.
La prima grande differenza tra la realizzazione di un archivio su file binario in linguaggio C/C++
oppure tramite database sta nel fatto che mentre nel primo caso occorre specificare in un
programma cosa cercare e come cercarlo all‟interno del file (ricordate, le istruzioni fread e fwrite,
fseek, ecc.), mentre nel secondo caso basta specificare cosa cercare, e non come: il modo in cui
avviene la ricerca è compito del DBMS, che farà questo al posto nostro, a patto che progettiamo
opportunamente il database in modo da permettergli le ricerche.
L‟uso di database risulta di grande utilità nella realizzazione di archivi di grandi dimensioni, come
ad esempio un sistema informativo aziendale, in cui molti utenti devono accedere a molti dati
collegati tra loro in modo complesso: scrivere del codice (in C++ o qualsiasi altro linguaggio di
programmazione) per accedere ogni volta a un archivio di questo tipo può risultare estremamente
sconveniente.
1
Progettazione di un database
Per progettare opportunamente una base di dati, occorre innanzitutto realizzare un modello
concettuale del database, solitamente in UML, che specifica quali entità sono coinvolte e quali
relazioni ci sono tra esse (si veda la dispensa sulla programmazione a oggetti), e successivamente
derivare da questo il modello logico, ossia lo schema di come è fatto il database.
Il database, come abbiamo già sottolineato nel paragrafo introduttivo, va opportunamente progettato
in modo da permettere al DBMS un facile e rapido accesso ai dati, e per garantire inoltre:
-
non ridondanza dei dati: evitare dati ripetuti inutilmente.
-
inconsistenza dei dati: evitare di avere dati privi di significato o di perdere dati significativi.
-
sicurezza: permettere l‟accesso ai dati solo alle persone autorizzate.
Modello concettuale: schema Entity/Relationship (E/R)
Come per la programmazione orientata agli oggetti, in questo modello si specificano quali entità
devono essere memorizzate, e come le diverse entità sono in relazione tra loro (da questo, il nome
di schema E/R). Si può usare un linguaggio grafico come UML per descrivere questo schema. In
questo caso, tuttavia, a differenza della OOP, non ha nessun senso parlare di metodi delle entità: ci
interessa solo memorizzare informazioni, e non metodi, cioè non cosa un‟entità sa fare. Per ogni
entità, dunque, andremo a definire solo la lista degli attributi che la caratterizzano.
Possiamo allora disegnare uno schema E/R usando un linguaggio UML semplificato rispetto a
quello utilizzato nella programmazione a oggetti, come nel seguente esempio:
Come si può notare dall‟esempio, non occorre più riportare nello schema E/R i metodi dell‟entità,
né il tipo dei diversi attributi (che andrà successivamente specificato nel modello logico del
database). Inoltre, si indicano con un pallino pieno gli attributi obbligatori, mentre si indicano con
un pallino vuoto gli attributi opzionali, quelli ai quali è possibile anche non attribuire un valore.
Infine, viene sottolineato un attributo (o un insieme di attributi) che costituisce una chiave
primaria, la quale permette di distinguere un elemento dall‟altro in modo univoco. Facciamo un
altro esempio:
2
insegna
N
N
L‟entità studente è composta dagli attributi obbligatori matricola, nome, cognome e dall‟attributo
opzionale classe. Ciò significa che quando inseriremo i dati di uno studente, dovremo inserire la sua
matricola, il suo nome, il suo cognome, e solo se lo vogliamo anche la classe. Inoltre, l‟attributo
matricola è chiave primaria: significa che ogni studente è distinto dall‟altro per il fatto che la
matricola è diversa. L‟entità docente, invece, è composta dagli attributi obbligatori id, nome,
cognome e dall‟attributo opzionale materia. La chiave primaria in questo caso è l‟attributo id (sta
per identificativo, che di solito è un codice univoco o un numero progressivo). Tra le due entità c‟è
una associazione generica con molteplicità N a N.
Perché lo schema concettuale sia valido, occorre che ogni attributo sia un dato semplice (non
composto, come gli array o i record), che può essere una stringa, un intero, un reale, ecc.
Modello logico: schema del database
Una volta disegnato il modello concettuale, si passa allo schema logico del database: si stabilisce
cioè come sono organizzate le informazioni dentro l‟archivio. Come abbiamo già detto, questo deve
essere fatto in modo tale da permettere al DBMS di recuperare facilmente ed efficientemente i dati.
Lo schema logico del database dipende dal tipo di database che si vuole realizzare. Esso può essere
di diversi tipi:
-
database gerarchico
-
database reticolare
-
database relazionale
-
database object oriented
I database gerarchici hanno un‟organizzazione ad albero: alcune informazioni dipendono
(discendono) da altre informazioni, a formare una sorta di albero genealogico. Per realizzare questo
tipo di database occorre memorizzare gli indirizzi delle informazioni “figlie” nelle informazioni
“padre” in modo da poterle recuperare: servono, quindi, i puntatori. L‟uso dei puntatori rende
piuttosto difficile e macchinosa la gestione di un database di questo tipo.
3
I database reticolari sono organizzati con puntatori come quelli gerarchici, solo che il grafo che
rappresenta le dipendenze tra le informazioni può essere qualsiasi, non necessariamente un albero
(ricordiamo che un albero è un particolare grafo, connesso e aciclico).
I database relazionali sono attualmente i più utilizzati in commercio, per la loro semplicità,
rapidità ed efficienza nella gestione dei dati. Tutti i DBMS elencati nel paragrafo introduttivo fanno
riferimento a database relazionali (per questo motivo prendono il nome di RDBMS). Essendo i più
utilizzati, sono quelli che tratteremo in questa dispensa e ne parleremo più in dettaglio tra poco.
I database object oriented sono i più recenti e hanno grande utilità in particolari applicazioni come
i database spaziali e in alcune aree finanziarie. Non hanno avuto, però, per la complessità di
gestione e per la difficoltà del linguaggio usato per reperire informazioni dal database, un grande
successo commerciale.
Il modello relazionale
Un database relazionale è composto da una o più relazioni o tabelle. Matematicamente, una
relazione è un sottoinsieme del prodotto cartesiano di due o più insiemi. Si faccia attenzione a non
confondere il concetto di relazione nel modello logico di un database, che corrisponde a una tabella,
con quello di relazione (che chiameremo d‟ora in poi associazione, per evitare confusione) nello
schema E/R che lega due entità tra loro.
ESEMPIO:
Siano dati gli insiemi A={1,2,3} e B = {x, y}. Il prodotto cartesiano degli insiemi A e B (si indica
AXB) è l‟insieme formato da tutte le possibili coppie ottenute prendendo un elemento di A e un
elemento di B. Qundi, abbiamo
AXB = {(1,x), (1, y), (2,x), (2, y), (3,x), (3, y)}
Essendo una relazione R un sottoinsieme del prodotto cartesiano, essa sarà formata solo da alcune
delle coppie possibili, come ad esempio
R = {(1, y), (2,x), (2, y)}
ESEMPIO:
Siano dati gli insiemi U = {Filippo, Marco, Gianni} e D = {Arianna, Sara, Fernanda} dei tronisti e
delle troniste della trasmissione Uomini e Donne. Consideriamo la relazione “fidanzarsi con”. Essa
è composta da alcune delle coppie possibili del prodotto cartesiano UXD (che ricordiamo, è
l‟insieme di tutte le possibili coppie formate da un uomo e una donna). Ad esempio, potremmo
avere
R = {(Filippo, Sara), (Gianni,Fernanda)}
ESEMPIO:
Siano dati gli insiemi A = {1, 2, 3}, B = {x, y}, C = {?, !}. Una relazione è un sottoinsieme del
prodotto cartesiano AXBXC, cioè formata da alcune delle possibili triple ottenute prendendo un
elemento dell‟insieme A, un elemento dell‟insieme B e un elemento dell‟insieme C. Ad esempio,
R = {(1, x, ?), (1, y, ?), (3, y, !)}
4
In generale, detti A, B, C,… i domini degli attributi a, b, c,… di un‟entità, cioè gli insiemi dei
possibili valori che ogni attributo può assumere (A è l‟insieme dei possibili valori che può assumere
l‟attributo a, B è l‟insieme dei possibili valori che può assumere l‟attributo b, ecc.), e supponendo di
avere n diversi attributi, una relazione R è un sottoinsieme di tutte le possibili n-ple (si legge
ennuple) ottenute prendendo un elemento di A, un elemento di B, un elemento di C, ecc.
Appare evidente come una relazione può essere vista come una tabella, in cui ogni riga corrisponde
a una n-pla e ogni colonna corrisponde a un diverso attributo. Con riferimento all‟ultimo esempio,
possiamo rappresentare la relazione R come
a b
c
1 x ?
1 y ?
3 y
!
Nel linguaggio dei database relazionali, ogni riga si chiama una tupla (per ricordare che si tratta di
triple o quadruple o quintuple o, in generale, n-ple) e ogni colonna si chiama campo, anziché
attributo. In una tabella, il numero di righe si chiama cardinalità della relazione, mentre il numero
di colonne si chiama grado della relazione.
Nelle figure seguenti mostriamo un esempio di tabella (o relazione, visto che sono la stessa cosa)
creata con il DBMS Base di OpenOffice: nella Figura 1 osserviamo la struttura della tabella, che ne
descrive i campi, ognuno con un proprio tipo di dato; nella Figura 2 mostriamo il contenuto della
tabella, ossia l‟insieme delle tuple che la compongono.
Figura 1
Figura 2
Per sinteticità, per descrivere la struttura di una tabella nel modello relazionale si usa spesso la
seguente notazione: con riferimento alla tabella studente della figura precedente, si può scrivere
Studente ( matricola, nome, cognome, età, classe )
dove matricola è la chiave primaria.
5
Regole di derivazione del modello logico dal modello concettuale
Per creare un database in modo coerente, cioè tale che il DBMS possa reperire le informazioni che
ci interessano con facilità ed efficienza, occorre seguire alcune regole. A partire dallo schema E/R,
si applicano le seguenti regole:
1. ogni entità diventa una tabella, con tante colonne (campi) quanti sono gli attributi dell‟entità,
con un‟eccezione: se c‟è un‟associazione 1 a 1 tra due entità, viene realizzata un‟unica
tabella in cui compaiono tutti gli attributi di entrambe le entità.
ESEMPIO:
diventa
ESEMPIO:
diventa
2. ogni associazione 1 a 0..1 viene realizzata inserendo una chiave esterna nella tabella
dell‟entità 0..1, che fa riferimento alla chiave primaria dell‟entità 1
ESEMPIO:
diventa
3. ogni associazione 1 a N viene realizzata inserendo una chiave esterna nella tabella
dell‟entità N, che fa riferimento alla chiave primaria dell‟entità 1
6
ESEMPIO:
diventa
4. ogni associazione N a N viene realizzata creando una nuova tabella che contiene solo le
chiavi primarie delle due entità, più eventuali attributi dell‟associazione.
ESEMPIO:
diventa
Operatori relazionali e SQL
Per interrogare il database, ossia per recuperare le informazioni memorizzate al suo interno, si usa
un linguaggio specifico, chiamato SQL (Structured Query Language, linguaggio strutturato di
interrogazione). Prima di descrivere come funziona, occorre spiegare che ogni interrogazione in
SQL è una combinazione di una o più tra tre operazioni relazionali che è possibile fare sul database:
1. Proiezione: si rappresenta con il simbolo  e crea una nuova tabella che contiene solo
alcune colonne di una tabella esistente (dunque, ne cambia il grado), nel seguente modo:
facendo sempre riferimento alla tabella Studente dell‟esempio di pagina 5, supponiamo di
voler estrarre solo gli attributi nome e cognome: scriveremo
nome, cognome (Studente)
ottenendo la tabella seguente:
7
2. Selezione: si rappresenta con il simbolo  e crea una nuova tabella che contiene solo alcune
righe di una tabella esistente (dunque, ne cambia la cardinalità), nel seguente modo:
facendo ancora riferimento alla tabella Studente di pagina 5, supponiamo di voler cercare gli
studenti che hanno più di 18 anni: scriveremo
età>18 (Studente)
ottenendo la tabella seguente:
Come si può vedere, l‟operazione di selezione richiede di esprimere una condizione, che può
essere una qualsiasi espressione booleana con operatori AND, OR e NOT, e operatori
matematici di confronto > , >= , < , <= , = ,  .
3. Congiunzione (join): si rappresenta con il simbolo
e crea una nuova tabella ottenuta
congiungendo insieme due tabelle su un attributo comune. Ad esempio, date le due tabelle
dove è stata posta una chiave esterna sigla_classe nella tabella Studente che fa riferimento
all‟attributo sigla della tabella Classe, per rappresentare l‟associazione 1 a N tra le due
entità, se si effettua un join tra le due tabelle sull‟attributo comune, cioè l‟operazione
Classe sigla
Studente sigla_classe
si ottiene la tabella
Per essere più chiari, facciamo un altro esempio: siano date le seguenti tabelle R1 e R2, con
attributo comune A.
8
Facciamo ora l‟operazione di join tra le due, sull‟attributo A, cioè R1A
R2A .
Otteniamo la nuova tabella
SQL
Nel linguaggio SQL, possiamo eseguire le tre operazioni relazionali viste (proiezione, selezione e
join) formulando un‟interrogazione (query, in inglese) nel seguente modo:
SELECT campi
FROM tabelle
WHERE condizioni
Nella prima riga si realizza l‟operazione di proiezione , cioè si scelgono (SELECT) i campi da
visualizzare della tabella.
Nella seconda riga si specificano le tabelle dalle quali (FROM) prendere i dati necessari alla nostra
l‟interrogazione. Se occorre effettuare uno o più join
tra tabelle, si elencano tutte le tabelle
separate da virgola.
Con la terza riga si realizza l‟operazione di selezione , cioè, si specificano le condizioni (WHERE)
di selezione delle righe della tabella, insieme alle condizioni di join (cioè, che il valore dell‟attributo
comune sul quale effettuare il join deve essere uguale).
Facciamo alcuni esempi:
-
Con riferimento alla tabella studente di pagina 5, vogliamo visualizzare il nome e il
cognome degli studenti della 5°A. Scriveremo
SELECT nome, cognome
FROM Studente
WHERE classe = 5A
9
-
Sempre con riferimento alla tabella studente di pagina 5, vogliamo visualizzare le diverse
età degli studenti della 4B. In questo caso, aggiungiamo la parola DISTINCT all‟operazione
SELECT in modo da non visualizzare valori ripetuti. Scriveremo, perciò,
SELECT DISTINCT eta
FROM Studente
WHERE classe = 4B
-
Facciamo un join: siano date le tabelle Studente e Classe mostrate nell‟esempio di pagina 8.
Vogliamo visualizzare il nome e il cognome degli studenti del secondo piano. Bisogna
congiungere insieme le due tabelle, poiché le informazioni nome e cognome di uno studente
sono nella tabella Studente, mentre l‟informazione piano è nella tabella Classe. Scriveremo
allora
SELECT nome, cognome
FROM Studente, Classe
WHERE piano = 2 AND sigla=sigla_classe
La prima delle due condizioni del WHERE realizza la selezione , scegliendo solo le righe
relativi a studenti del secondo piano, mentre la seconda è la condizione per fare la
congiunzione tra le due tabelle.
In molte implementazioni di SQL, per una maggior chiarezza, si richiede che il nome dei campi sia
preceduto dal nome della tabella di cui il campo fa parte, separati da un punto. Ad esempio,
nell‟ultima interrogazione vista, dovremo scrivere
SELECT Studente.nome, Studente.cognome
FROM Studente, Classe
WHERE Classe.piano = 2 AND Classe.sigla=Studente.sigla_classe
Oltre alle operazioni viste, SQL mette a disposizione molti altri strumenti per effettuare conteggi
(COUNT), somme (SUM), medie (AVG), ecc, oltre alla possibilità di effettuare interrogazioni più
complesse come query di risultati di altre query (query annidate tra loro). Al momento, questo
approfondimento non rientra negli scopi di questa dispensa.
IL DBMS di OpenOffice: Base
Come abbiamo già anticipato, Base è un DBMS gratuito fornito con il pacchetto OpenOffice, e
come il più famoso Access di Microsoft Office (che però è a pagamento), ha un‟interfaccia grafica e
procedure guidate per la creazione di tabelle, per la realizzazione delle query, per definire delle
viste (sono regole di visibilità che definiscono quali utenti possono vedere quali tabelle o porzioni
di esse: si pensi a un database aziendale: il reparto produzione non deve necessariamente vedere le
tabelle dei dati del reparto amministrazione, e viceversa), preparare formulari e rapporti, e molte
altre caratteristiche.
10
All‟avvio, Base presenta la seguente finestra, per scegliere se creare un nuovo database o aprirne
uno già esistente:
Una volta fatta la scelta, se si tratta di un nuovo database Base ci chiede di registrarlo (serve a poter
usufruire di funzioni messe a disposizione da OpenOffice, come la condivisione in rete e il controllo
degli accessi) e salvarlo. Si arriva così alla schermata principale:
Per creare una nuova tabella, si può usare la procedura guidata o fare click su Crea tabella in vista
struttura. Nel secondo caso, si apre la seguente schermata
11
che permette di definire i campi della tabella e i loro tipi, di inserirne una descrizione informale, e di
assegnare una chiave primaria (basta fare click destro sul campo che deve diventare chiave) alla
tabella. ATTENZIONE: Base richiede che ogni tabella abbia una chiave primaria, che può essere
costituita da un solo campo!
Una volta definita la struttura di una tabella, la si salva e la si ritrova visualizzata nella lista delle
tabelle nella schermata principale. Per vedere il contenuto della tabella, o per inserirvi dati, basta
fare doppio click su di essa.
Per realizzare una query, basta fare click sulla voce Ricerche nella schermata principale, aprendo la
seguente schermata
A questo punto è possibile definire un‟interrogazione (o query, o ricerca) in modalità struttura, in
modalità SQL, o usando una procedura guidata. ATTENZIONE: l‟SQL di Base richiede che i nomi
delle tabelle e i nomi dei campi siano racchiusi tra doppi apici, e che i valori costanti siano racchiusi
tra singoli apici! Ad esempio, la query
12
SELECT Studente.nome, Studente.cognome
FROM Studente, Classe
WHERE Classe.piano = 2 AND Classe.sigla=Studente.sigla_classe
si scrive nell‟SQL di Base nel seguente modo:
SELECT “Studente”.”nome”, “Studente”.”cognome”
FROM “Studente”, “Classe”
WHERE “Classe”.”piano” = „2‟ AND “Classe”.”sigla”=”Studente”.”sigla_classe”
Se si sceglie di definire la query in modalità struttura, invece, si apre la seguente schermata:
Innanzitutto, si scelgono le tabelle che si vogliono utilizzare nella query (si noti che è possibile
anche scegliere le tabelle ottenute con delle query già memorizzate). Queste verranno poste in alto e
sarà possibile collegarle tra loro per effettuare le congiunzioni (basta trascinare uno sull‟altro
l‟attributo comune), come nel seguente esempio:
Ora, bisogna impostare le operazioni di selezione e proiezione: si scelgono i campi nella parte
inferiore della schermata, impostando l‟opzione visibile se devono essere visualizzati (è la
proiezione), e impostando eventuali criteri di selezione delle righe. Mostriamolo con un esempio:
13
con riferimento alle due tabelle Studente e Classe della figura precedente, realizziamo in questa
modalità la query
SELECT “Studente”.”nome”, “Studente”.”cognome”
FROM “Studente”, “Classe”
WHERE “Classe”.”piano” = „2‟ AND “Classe”.”sigla”=”Studente”.”sigla_classe”
dovremo fare come segue:
Per esercizio, si aggiunga una tabella Docente (id, nome, cognome, materia) alle due tabelle del
precedente esempio, e una tabella Docente-Classe (id, id_docente, id_classe) per realizzare
l‟associazione N a N tra le tabelle Docente e Classe. Dopo aver popolato (inserito dei dati) il
database, si esegua la seguente ricerca (o query, o interrogazione): visualizzare il nome e il
cognome di tutti gli studenti che seguono Informatica. Si osservi successivamente il codice SQL
della ricerca generato dalla modalità struttura di Base (click destro sulla query, poi Modifica in vista
SQL).
Normalizzazione del database
Perché un database sia opportunamente organizzato, esso deve essere progettato in modo da non
presentare anomalie, che si verificano spesso quando i dati presenti nel database sono ridondanti
(più copie inutili degli stessi dati). Le anomalie che possono verificarsi sono di inserimento, di
modifica e di cancellazione. Facciamo un esempio:
Supponiamo di avere la seguente tabella, in cui il codice del prodotto è la chiave primaria:
14
appare evidente che la tabella non è ben strutturata, in quanto ci sono parecchi dati ripetuti
inutilmente. Possono verificarsi, in questo caso, le seguenti situazioni:
-
Anomalia di inserimento: se abbiamo un nuovo magazzino che non contiene prodotti, non
possiamo aggiungerlo al database.
-
Anomalia di modifica: se cambia l‟indirizzo di un magazzino, occorre cambiarlo in tutte le
tuple dove compare.
-
Anomalia di cancellazione: se si svuota un magazzino, perdiamo le informazioni sul suo
indirizzo.
Per risolvere questo problema, si effettua un processo di normalizzazione del database, utilizzando
in sequenza (una dopo l‟altra) tre diverse forme normali:
Prima forma normale (1FN): Una tabella si dice in prima forma normale quando rispetta i
requisiti del modello relazionale, cioè, ogni attributo è formato da un dato elementare, non ci sono
elementi uguali tra loro nella relazione (tuple o righe uguali), non ci sono attributi ripetuti.
Seconda forma normale (2FN): Una tabella si dice in seconda forma normale se è in 1FN e non ci
sono attributi che dipendono parzialmente dalla chiave primaria; è il caso in cui la chiave primaria è
formata da più di un attributo, e c‟è un terzo attributo che dipende solo da una parte della chiave.
ESEMPIO: Supponiamo che nella tabella della figura precedente la chiave primaria sia composta
dalla coppia di attributi prodotto, magazzino, cioè che la nostra tabella sia la seguente
Inventario (prodotto, magazzino, quantità, indirizzo)
Chiaramente, l‟attributo indirizzo dipende solo dall‟attributo magazzino, che è parte della chiave. Si
può risolvere questa situazione realizzando due tabelle nel seguente modo:
Inventario (prodotto, quantità, id_magazzino)
Magazzino (id, indirizzo)
Terza forma normale (2FN): Una tabella si dice in terza forma normale se è in 2FN e non ci sono
dipendenze transitive, cioè attributi che dipendono indirettamente dalla chiave, ma da altri attributi
non chiave. E‟ l‟esempio della tabella in figura:
Inventario (prodotto, magazzino, quantità, indirizzo)
L‟attributo non chiave indirizzo (del magazzino) dipende dall‟attributo non chiave magazzino, il
quale dipende dall‟attributo prodotto, che è chiave. Per risolvere questa situazione, si può procedere
come nel caso della 2FN, creando due tabelle
Inventario (prodotto, quantità, id_magazzino)
Magazzino (id, indirizzo)
15
ESEMPIO: Facciamo un altro esempio, con la seguente tabella:
Studente (matricola, nome, cognome, scuola, telefono_scuola)
Si vede chiaramente che anche in questo caso c‟è una dipendenza transitiva: l‟attributo
telefono_scuola dipende dall‟attributo scuola, che non è chiave primaria. Si può risolvere la
situazione creando le due tabelle seguenti, al posto di quella data:
Studente (matricola, nome, cognome, id_scuola)
Scuola (nome_scuola, telefono_scuola)
E‟ opportuno sottolineare, comunque, che una buona progettazione concettuale del database (lo
schema E/R) ci darà tabelle che già rispettano tutte e tre le forme normali, senza bisogno di
effettuare un processo di normalizzazione.
16