Franco Niccolucci
Università di Firenze
1. Introduzione
Uno
degli utilizzi più diffusi dell’informatica è la gestione di archivi di dati.
In particolare, quando le informazioni possono essere rappresentate da testi o
quantità (intese in senso lato: ad esempio, date), i dati e gli archivi che li
contengono sono detti alfanumerici.
Naturalmente
il sistema di archiviazione prevede la possibilità di reperire le informazioni
che vi sono contenute in modo rapido, efficiente e sicuro: in tal caso il sistema
prende il nome di base di dati o database. Un database è quindi un
sistema di archiviazione di dati con un’organizzazione finalizzata al
reperimento delle informazioni che essi contengono, in modo efficiente (nel
senso delle prestazioni) e sicuro (nel senso di non perdere
informazioni). Il modo con cui le informazioni vengono cercate (interrogazione
del database) non è necessariamente semplice o agevole: tuttavia, quasi tutti i
database sono dotati di un’interfaccia, cioè una modalità operativa, di
uso relativamente semplice. Va notato, comunque, che tanto più è sofisticato
l’uso che si intende fare del database, tanto meno è probabile che si possa
usare un’interfaccia facile. Si deve quindi distinguere fra database (gli
archivi) e sistema di gestione del database o DBMS (Data Base
Management System), a suo volta costituito da motore del database (tecniche
e programmi per ricercare i dati), sistema di interrogazione e interfaccia
utente.
Per
utilizzare un DBMS ci si avvale quindi di un linguaggio di interrogazione: ogni
interrogazione è cioè costituita da comandi, frasi scritte secondo regole
rigidamente codificate con le quali si richiede l’esecuzione di determinate
elaborazioni.
A
questa interfaccia a comandi va spesso a sovrapporsi (talvolta sfruttando
sistemi appositamente progettati per questo) un’interfaccia utente di tipo
grafico (Graphical User Interface o GUI).
Poiché
non è conveniente sviluppare DBMS finalizzati alla risoluzione di un solo
problema, sono disponibili pacchetti (gruppi di programmi) genericamente in
grado di gestire database rispondenti a determinati requisiti, che per essere
utilizzati in un caso specifico richiedono una fase di personalizzazione, cioè
di adattamento al problema e ai dati effettivamente da gestire.
È dunque necessario progettare accuratamente il
sistema dei dati, in modo relativamente indipendente dalle caratteristiche del
prodotto che poi si impiegherà per gestirlo. Infatti queste caratteristiche
potrebbero condizionare eccessivamente la fase di progettazione, da un lato
limitando la flessibilità del sistema per limiti del software di riferimento e
dall’altro introducendo elementi non standard e quindi di difficile
manutenzione nel tempo.
Ci
si deve, al contrario, rifare, in fase di progettazione, a modelli del
tutto generali, che solo successivamente saranno realizzati (implementati)
utilizzando un determinato software. In questo modo, inoltre, si potrà
chiaramente distinguere fra limiti dovuti al modello generale utilizzato e
limiti invece dovuti al software poi effettivamente impiegato, scelto magari
per considerazioni di altra natura (disponibilità, costo, facilità d’uso). Si
dovrà quindi progettare il sistema prima di tutto a livello concettuale/semantico,
individuando i soggetti portatori di informazione, le loro caratteristiche e le
mutue interrelazioni. Da questo si potrà poi derivare il modello logico,
in cui verrà tracciato lo schema della struttura dati corrispondente a quella
informativa reale, che sarà successivamente implementato usando il
software prescelto. Raramente, o per meglio dire quasi mai, ci si dovrà
occupare del modello fisico, cioè di come i dati sono memorizzati nel
computer, lasciando tale compito al software, che assicurerà l’integrità delle
informazioni archiviate.
Il
modello che prenderemo in considerazione è di applicabilità generale nel caso
che le fonti di informazione possano essere strutturate, cioè che sia
possibile classificarle come appartenenti a determinate tipologie, ciascuna
delle quali ha le stesse caratteristiche. Questo primo passaggio è solo
apparentemente semplice: è infatti frequente il caso in cui il livello di
generalizzazione che consente questa classificazione impoverisce eccessivamente
l’informazione rispetto alle necessità della ricerca. Va comunque tenuto presente
che la classificazione o meglio la strutturazione delle informazioni prende in
considerazione solo le caratteristiche utili per le finalità del sistema di
archiviazione.
In
campo storico, questa selezione presenta non poche difficoltà ed è oggetto di
un acceso dibattito sulla sua effettiva possibilità. Un modo ragionevole, a mio
avviso, di risolvere la questione è considerare la creazione del database una
sorta di “edizione strutturata” delle fonti.
Porre
in questi termini la questione riporta nel giusto ambito il problema se la
tecnologia utilizzata è adeguata: lo è tutte le volte che una tale “edizione”
ha un senso storiografico, per la natura delle fonti, le loro caratteristiche,
la loro estensione. Questo approccio, inoltre, restituisce dignità ad
un’attività altrimenti considerata secondaria nella ricerca storica e può
suggerire ampliamenti ed estensioni che la valorizzino come prodotto autonomo
della ricerca stessa. D’altronde il concetto di edizione implica quello di
pubblicazione, e quindi si apre tutto un altro capitolo, che non affronteremo
in questa sede, relativo alla pubblicazione dei database come esito della
ricerca, potenziale strumento per altri ricercatori e comunque patrimonio
scientifico universale.
·
le fonti hanno una
struttura coerente
·
gli elementi portatori
di informazione sono coerenti, ben definiti e chiaramente individuabili
·
si può individuare una
strategia efficiente nei riguardi di elementi anomali (unità di misura, valuta,
cronologia, caratteri inusuali), incoerenti (variazioni nella grafia),
indefiniti (di nuovo la cronologia o la designazione di persone) o errati.
Si osservi che comunque è necessario risolvere i
problemi che derivano dagli ultimi due punti, a prescindere dall’uso del
computer per organizzare i dati. In sostanza, quindi, il punto decisivo è il
primo, riguarda cioè la prevalenza della caratteristica “testuale” rispetto a
quella “strutturata”: non soltanto le caratteristiche proprie delle fonti, ma
anche, e soprattutto, in riferimento all’indagine che si deve condurre. Di
nuovo, considerare il database un’edizione strutturata sposta la questione in
campo storico e permette, di solito, una risposta ragionevole.
Alcune ricerche hanno affrontato il problema di
individuare modelli teorici più confacenti alla ricerca storica rispetto a
quelli strutturati: in tal senso si sono mosse le proposte di Thaller (si veda
la bibliografia relativa, peraltro di non facile reperibilità, citata nel
volume di Townsend, Chappel e Strujvé indicato in bibliografia) e, molto
recentemente, di altri (si veda la sessione dedicata allo Historical Text
Encoding nelle conferenze DRH e E-AHC tenute a Londra nel settembre 1999).
Va detto, in ogni modo, che il modello strutturato fornisce risposte
soddisfacenti a gran parte dei problemi.
Diverso e in un certo senso più semplice è il caso dei
dati archeologici, in quanto questa disciplina ha da tempo stabilito al proprio
interno strumenti descrittivi strutturati, di facile trasposizione in ambito
informatico. In parte, comunque, si ripropone la stessa difficoltà quando si
intende prendere in considerazione il cosiddetto “diario di scavo”, per il quale
recentemente (n. 11/1999 di Archeologia e Calcolatori, di prossima
pubblicazione) sono state proposte soluzioni alternative.
2.
Modelli
concettuali: il modello entità – relazioni.
Come
si è detto, il modello concettuale è indipendente dalla particolare
realizzazione (hardware e software) e fornisce un contesto per lo sviluppo
della struttura del database (schema).
I
paradigmi più comuni per la descrizione dei modelli concettuali sono
·
il metodo entità –
relazioni (entity – relationships o ERM, Entity–Relationship Modelling)
·
il metodo a oggetti.
In
questa sede prenderemo in esame soltanto il metodo ERM che si presta
perfettamente ai problemi in esame.
I concetti principali del metodo ERM sono i seguenti.
Entità (entity) – Ogni soggetto portatore di
informazione.
Classe di entità (class) – Insieme di entità simili,
ai fini del problema in studio.
Attributo (attribute) – Proprietà delle entità rilevanti
ai fini del problema.
Tutte
le entità di una stessa classe possiedono gli stessi attributi, eventualmente
con valore diverso. Due entità di una stessa classe sono distinguibili in
quanto almeno uno dei loro attributi ha un valore diverso, quindi due entità
della stessa classe i cui attributi hanno tutti lo stesso valore non sono
distinguibili.
Relazione (relationship) – Connessione logica fra classi
di entità, che determinano relazioni fra singoli soggetti (entità) delle classi
stesse.
Ad
esempio la relazione “autore di” fra le classi “Persone” e “Libri” si esplica
stabilendo che “Manzoni” è autore di “I promessi sposi”. Quindi una relazione
divide le possibili coppie (abbinamenti) formate con i soggetti di una classe e
quelli di un’altra in due insiemi: l’insieme delle coppie che si corrispondono
nella relazione (nell’esempio precedente le coppie autore – opera) e le altre
(abbinamenti casuali, come “Manzoni” – “La Divina Commedia”). Una relazione è
direzionale, nel senso che ha rilevanza l’ordine in cui si enuncia la
corrispondenza (“Manzoni è autore dei Promessi Sposi” è diverso da “I Promessi
Sposi sono autori di Manzoni”). Ciò significa che ogni relazione definisce
implicitamente anche la relazione inversa (“autore di” ® “scritto da”).
Evento (event) – Modifica avvenuta nel tempo del
valore di un attributo di un’entità o di una relazione (una coppia appartenente
alla relazione non lo è più e/o una coppia non appartenente alla relazione ora
vi appartiene).
Chiave (key) – attributo o insieme di attributi
(chiave composta) che identifica, in modo univoco, un’entità all’interno della
classe di appartenenza: soggetti diversi hanno chiavi diverse.
Gerarchia (hierarchy) – tipo speciale di relazione che
determina l’ereditarietà degli attributi; una delle due classi è, in effetti,
una specializzazione dell’altra ed ha, perciò, ulteriori attributi rispetto
alla prima. Ad esempio, si può definire una classe di “eventi storici” con
attributi data e luogo e poi definire la classe delle “battaglie” come
specializzazione degli “eventi storici”, dotata quindi degli stessi attributi,
con in più altri (comandanti, eserciti in campo, ecc.) che la classe più
generale non possiede. Ogni chiave per la classe più generale è anche una
chiave, detta chiave derivata, per la classe derivata (borrowed key).
Le
classi, gli attributi e le relazioni possono essere rappresentati in un
diagramma che utilizza simboli convenzionali:
·
rettangoli per le classi
·
cerchi per gli attributi
·
rombi per le relazioni,
rappresentate come una linea che congiunge le classi.

Il
diagramma precedente illustra il caso di due entità A (con attributi p, q, r) e
B (con attributi x, y) connesse dalla relazione C.
Una
relazione fra due classi A e B può essere:
1 a 1 (uno-a-uno): in tal caso essa fa corrispondere 1
entità di A ad 1 entità di B. Possono esistere elementi di A oppure di B che
non hanno corrispondenti nella relazione, ma non può esistere alcun entità, né
di A né di B, che compaia due volte, abbinata con entità diverse.
1 a N (uno-a-molti): in tal caso ad un’entità di A possono
corrispondere più entità di B. Non è, invece possibile che la stessa entità di
B corrisponda a entità distinte di A.
N a M (molti-a-molti): in tal caso a entità distinte di A
possono corrispondere entità distinte di B e viceversa.
La
relazione N a 1 cioè molti-a-uno è l’inversa di una relazione uno-a-molti.
Questa
tipologia prende il nome di molteplicità della relazione.
3.
Un esempio di
applicazione
Vediamo
in un esempio l’applicazione del modello entità – relazioni.
Si
intende creare un database contenente le delibere prese da un’assemblea
elettiva (ad esempio, consiglio comunale).
I
dati che interessano sono i seguenti:
·
Titolo della delibera
·
Data di votazione della
delibera
·
Oggetto secondo una
descrizione standardizzata
·
Presidente della seduta
·
Proponente della
delibera
·
Votanti (nomi)
·
Risultato della
votazione.
Poiché lo scopo dell’indagine è analizzare il
comportamento dei consiglieri rispetto alla propria affiliazione politica e
rispetto alla propria collocazione sociale, per ciascun consigliere si
archivieranno le relative informazioni, avendo predisposto una lista di casi
possibili per ciascuna in modo da standardizzarne la descrizione.
Si
aggiungono quindi alla lista precedente:
·
Affiliazione
·
Professione
Per
quanto riguarda l’oggetto delle delibere, un’indagine preliminare fa
riscontrare la presenza di delibere con oggetti “multipli”, concernenti cioè
argomenti diversi.
Per
semplicità, si supporrà in un primo momento che la seduta sia presieduta sempre
dalla stessa persona, salvo poi considerare il caso più generale.
Un
primo esame del problema porta ad individuare quattro entità: la delibera, i
consiglieri, la seduta e la votazione. Descriviamo le caratteristiche rilevanti
di ciascuna.
Delibera: ha un titolo e un oggetto;
è proposta da un consigliere; è votata in una votazione.
Consigliere: ha un’affiliazione politica e una professione; può essere
proponente di una delibera; può essere presidente di una seduta; partecipa a
una votazione
Votazione: ha un risultato numerico; riguarda una delibera; sono
presenti consiglieri.
Seduta: ha
una data; è presieduta da un consigliere.
Possiamo
semplificare questo modello riscontrando che l’entità seduta non ha
praticamente contenuti informativi, potendosi trasferire alla votazione le
caratteristiche individuate per essa. In questo modo si generalizza addirittura
il modello, potendosi considerare presidenti diversi nella stessa seduta e
sedute che durano più giorni, quindi con date diverse, mentre l’attimo della
votazione è certo, come pure chi riveste, in quel momento, il ruolo di
presidente.
Si
ottiene allora il modello descritto nella tabella seguente.
|
Entità/attributi |
Relazioni |
Con l’Entità
|
Moltepl.
|
Delibera
Titolo
Oggetto |
È proposta da |
Consigliere |
N-M |
|
|
È
votata in |
Votazione |
1-1 |
Consigliere
Nome
Affiliazione
Professione
|
Propone
|
Delibera |
M-N |
|
|
Presiede
|
Votazione |
1-N |
|
|
Partecipa
a |
Votazione |
M-N |
Votazione
Risultato
Data |
È
presieduta da |
Consigliere |
N-1 |
|
|
Vi
partecipa |
Consigliere |
N-M |
|
|
Vota
|
Delibera |
1-1 |
Nella tabella è stata anche introdotta la molteplicità
delle relazioni: esaminiamola in dettaglio.
Ogni delibera può
essere proposta da più consiglieri; ogni consigliere può proporre più delibere:
è una relazione molti-a-molti.
In ogni votazione si vota una sola
delibera; ogni delibera è votata una sola volta: è una relazione uno-a-uno.
Ogni votazione è presieduta da un
consigliere; ogni consigliere presiede più votazioni: è una relazione uno-a-molti (un
consigliere-presidente, molte votazioni)
Ad ogni votazione partecipano più consiglieri; ogni
consigliere partecipa a più votazioni: è una relazione molti-a-molti.
Si
noti che le relazioni sono state inserite due volte, considerando ogni volta la
relazione e la sua reciproca; naturalmente alla fine le si considererà una sola
volta, trattandosi della stessa relazione.
Il
diagramma risulta il seguente.

Si ovvierà allora a questa mancanza introducendo
attributi “artificiali” da usare come chiave, per esempio un numero progressivo
per ciascuna classe o un numero progressivo generale per gli oggetti creati nel
database. La scelta dipenderà dal sistema più semplice per l’utilizzo, di
solito una numerazione progressiva all’interno di ciascuna classe.
Il
modello relazionale è il più diffuso modello logico di struttura dati.
In
esso il database è rappresentato come un insieme di tabelle. I concetti
principali sono i seguenti.
Relazione (relation): tabella bidimensionale, per
evitare confusione chiamata anche semplicemente tabella (table).
Attributo (attribute):
colonna della tabella. Chiamato anche colonna (column) e campo
(field).
Dominio di un attributo (domain): insieme dei valori
ammissibili per quell’attributo.
Tupla (tuple): riga (row) della
tabella, chiamata anche record
·
Non sono permesse tuple
doppie
·
Non è ipotizzata
l’esistenza di un ordine particolare delle tuple.
Chiave (key): attributo/colonna della tabella o
insieme di colonne il cui valore identifica in modo univoco la tupla.
·
Esiste sempre una chiave
·
Possono esistere più
chiavi, fra cui se ne sceglie una arbitrariamente (cioè con criteri estranei
alla struttura dati).
E’
sempre possibile definire, dunque, una chiave: infatti, nell’ipotesi estrema,
l’insieme di tutte le colonne è una chiave, in quanto non possono esistere due
righe identiche. Di solito, comunque, la chiave sarà costituita da una sola
colonna o comunque un numero ridotto di colonne. In una tabella si può spesso
scegliere fra più chiavi possibili: la scelta è dettata, in tal caso, da
considerazioni esterne alla progettazione (semplicità – compattezza –
significatività rispetto al problema in studio), essendo da un punto di vista
operativo del tutto arbitraria. >Le chiavi possibili, ma non utilizzate,
sono chiamate chiavi candidate (candidate key).
Per
quanto riguarda una tabella, è necessario distinguere tra schema e estensione.
Lo schema è la descrizione della struttura, e ne definisce il numero e il nome
degli attributi, i loro domini, le eventuali chiavi. L’estensione è invece il
contenuto, cioè l’insieme delle tuple con i valori rispettivamente assegnati a
ciascun attributo di esse.
Rispetto
al modello concettuale sopra descritto, una tabella è una struttura in cui sono
contenuti gli attributi di una particolare classe di entità (corrispondenti
ciascuna a una tupla, riga della tabella) ovvero è contenuta una relazione.
Occorre
distinguere fra relazione (relationship), nozione del modello
concettuale sinonimo di corrispondenza fra classi di entità, e relazione
(relation), nozione del modello logico dei dati sinonimo di tabella. Per
questo, in italiano si usa il termine originale inglese o la si chiama tabella.
Per
derivare il modello (logico) relazionale corrispondente a un dato modello
(semantico) entity-relationship si possono seguire le seguenti regole:
·
Occorre una tabella
distinta per ogni classe di entità
·
Per definire una tabella
che rappresenta una classe di entità, si associa una colonna della tabella a
ciascun attributo della classe.
·
Per rappresentare una
relazione uno-a-uno fra due classi è sufficiente descrivere le corrispondenze
fra le chiavi delle tabelle corrispondenti, introducendo come attributo in una
qualsiasi delle due tabelle la chiave dell’altra. Ogni tupla di tale tabella
sarà composta dal valore dei propri attributi e nella colonna aggiuntiva avrà
il valore della tupla corrispondente nell’altra.
·
Per rappresentare una
relazione uno-a-molti fra due classi è sufficiente descrivere le corrispondenze
fra le chiavi delle tabelle corrispondenti, introducendo come attributo nella
tabella del lato “molti” la chiave della tabella del lato “uno”. Ogni tupla di
tale tabella sarà composta dal valore dei propri attributi e nella colonna
aggiuntiva avrà il valore della chiave della (unica) tupla a cui essa
corrisponde.
·
Per rappresentare una
relazione molti-a-molti è necessaria un’apposita tabella, in cui sono presenti
come attributi le chiavi delle due classi che si corrispondono nella relazione.
Il contenuto della tabella, cioè le sue tuple, sono coppie di chiavi di
elementi corrispondenti.
Quando
in una tabella è presente un campo che corrisponde alla chiave di un’altra
tabella, allo scopo di collegarne i contenuti informativi (come nel caso sopra
descritto delle tabelle che rappresentano relazione molti-a-molti), tale campo
prende il nome di chiave esterna (foreign key).
La descrizione del database
viene di solito compiuta in termini astratti, senza far riferimento ad una sua
particolare implementazione, cioè alla sua realizzazione concreta che impiega
un DBMS (Data Base Management System). Spesso per brevità anche
quest’ultimo viene chiamato impropriamente database, confondendo l’oggetto
dell’elaborazione con il software di elaborazione. Essa deve contenere i
seguenti elementi:
·
Nome delle tabelle che
compongono il database
·
Nome degli attributi di
ciascuna tabella
·
Dominio di ciascun
attributo
·
Chiave prescelta per
ciascuna tabella
Per
l’implementazione, questa descrizione deve essere tradotta nel linguaggio di
descrizione dati del DBMS prescelto oppure va immessa nel sistema per mezzo
della GUI, se disponibile. (Vedremo un esempio del primo caso applicato al
database delle delibere).
Ogni
DBMS ha un proprio insieme nativo di tipi di dati, che è in grado di gestire, e
per passare all’implementazione è necessario definire i domini in termine dei
tipi di dati ammessi. Ad esempio, un attributo con dominio “data” può avere
come tipo di data quello “data” solo se il DBMS lo consente; altrimenti ci si
dovrà arrangiare con altri tipi, ad esempio un tipo “testo” in cui si registra
la data come un testo nella forma in cui viene scritta. La scelta del tipo di
dato è legata prima di tutto, naturalmente, al dominio dell’attributo, ma
soprattutto alle operazioni che vi si devono compiere, anche solo
concettualmente. Nel caso suddetto della data, la sua codifica come “testo”
impedisce di compiere semplici operazioni come “un anno dopo”.
Per
questo a volte la scelta del tipo di dato è apparentemente astrusa: nello
stesso esempio, converrebbe codificare la data come numerico, rappresentandola
come numero di giorni trascorsi da un inizio prefissato, il che consentirebbe
di compiervi operazioni del tipo richiesto, a prezzo di una pressoché totale
illeggibilità del dato. Si tratta quindi di un compromesso, che può venire
aiutato da opportune funzioni di conversione di cui è dotato il DBMS.
5.
Operazioni sui
dati e sulle tabelle
Le operazioni più comuni di
manipolazione dei dati sono costituite dalle seguenti:
·
inserimento di dati (insert)
·
cancellazione di dati (delete)
·
modifica di dati (update)
detta anche aggiornamento
·
ricerca di dati (retrieve)
·
visualizzazione di dati
(report)
Altre
operazioni riguardano la manutenzione del database, come il suo compattamento,
che ottimizza i formati interni di archiviazione, il backup, la creazione di
indici, cioè di file ausiliari per migliorare le prestazioni durante le
operazioni di ricerca. Altre ancora riguardano la struttura dati, come la
creazione di tabelle e la loro modifica o cancellazione.
Una
ricerca di dati viene anche chiamata interrogazione (query) del
database.
Le
operazioni di inserimento, cancellazione, aggiornamento sono in genere
standard. Possono utilizzare maschere (form) che facilitano il compito
dell’operatore.
La
complessità dei report riguarda le modalità di visualizzazione e quindi le
caratteristiche “tipografiche” dell’output. Quasi tutti i DBMS dispongono di
formati standard di output e della possibilità di modificarli o di definirne di
propri. Un report opera su un insieme predefinito di dati, risultato di una
query.
Maggiore
attenzione va quindi dedicata alle ricerche, che per loro natura non seguono
uno schema fisso e quindi necessitano di modalità operative più flessibili e
per questo più complesse.
Una
query conduce alla definizione di un sottinsieme delle tuple del database. Si
può utilizzare una delle forme standard di visualizzazione per prendere
conoscenza dei risultati della query, oppure la query può essere utilizzata per
operazioni diverse, ad esempio il conteggio delle tuple rispondenti a
determinate condizioni oppure la creazione di un database estratto da quello
dato.
Una
query si basa su operazioni sulle tabelle, in conseguenza delle quali si
ottengono nuove tabelle da esse derivate. Le nuove tabelle così ottenute non
sono permanenti, nel senso che non sono automaticamente archiviate nel database
in modo permanente (a meno che non se ne faccia esplicita richiesta) in quanto
sono destinate a un uso transitorio. In genere, quindi, una query successiva
cancella il risultato della precedente, come un’operazione su una calcolatrice
cancella i risultati delle operazioni precedenti.
Le
operazioni più importanti sulle tabelle, utilizzate per le query, sono le
seguenti.
·
Selezione: una selezione opera su una sola tabella e produce
come risultato una sottotabella di questa, formata da un sottoinsieme delle sue
tuple, che conservano inalterate i loro attributi. In genere, quindi il
risultato di una selezione è costituito da una tabella con lo stesso numero di
colonne e un numero minore (o tutt’al più uguale) di righe. La scelta delle
tuple da inserire nel risultato è dettata da condizioni prescelte.

·
Proiezione: una proiezione opera su una sola tabella, producendo
come risultato una sua sottotabella formata dalle stesse tuple ma con un
sottinsieme degli attributi originari. In genere quindi la proiezione di una
tabella ha lo stesso numero di righe ma un numero minore (o tutt’al più uguale)
di colonne. Anche in questo caso la scelta delle colonne da inserire nel
risultato è dettata da condizioni prescelte, di itpo Sì/No.

·
Join: opera su due tabella producendone una nuova le cui
tuple risultano dalla combinazione di una tupla della prima e di una tupla
dell’altra, secondo determinate regole stabilite dall’operazione in
svolgimento. In questo caso perciò le colonne della nuova tabella saranno
composte da quelle della prima e da quelle della seconda, mentre le righe
saranno in numero variabile, in quanto gli abbinamenti dipenderanno dalle
condizioni stabilite dal join: il caso estremo è costituito da un join senza
condizioni in cui ogni tupla della prima tabella è abbinata a ogni tupla
dell’altra. Più frequente è il join corrispondente a una relazione fra le due
tabelle, in cui vengono abbinate le tuple che si corrispondono nella relazione.

Ad
esempio, in un database composto dalle due tabelle “autori” e “libri”, una
selezione sugli “autori” è definita dalla condizione “nati nel XX secolo” e
produce la tabella “autori nati nel XX secolo”, in cui ciascuna riga conterrà
tutti gli attributi del relativo autore. Una proiezione sugli autori è definita
dalla condizione “nome e cognome degli autori”, e produce una tabella con tutti
gli autori ma contenente soltanto i loro nomi e cognomi. Un join fra le due
tabelle è generato, ad esempio, dall’attribuzione ad ogni autore dei suoi
libri: la tabella così prodotta ha tutti gli attributi dell’autore (nome,
cognome, data di nascita, ecc.) e del libro (titolo, editore, ecc.), ma le sue
tuple corrispondono soltanto ad abbinamenti reali, escludendo casi come
“Alessandro Manzoni La Divina Commedia” perché esclusi dalla condizione prescelta.
In
linea di principio, la condizione di query può essere del tutto arbitraria o
assente. Ad esempio, la tupla “Alessandro Manzoni La Divina Commedia”
apparentemente illogica potrebbe divenire logica se lo scopo della query fosse
quello di determinare per ogni autore le opere a sua disposizione: in questo
contesto la tupla suddetta non sarebbe illogica, mentre lo sarebbe “Alessandro
Manzoni Ulisse”. Questo per sottolineare come la logicità o meno di
un’operazione dipenda da considerazione estranee al modello e il funzionamento
delle operazioni vada considerato o descritto soltanto in base alla coerenza
interna di essa.
I modi di esprimere le
operazioni e le query formano il linguaggio di interrogazione, che è, con
alcune varianti, uno standard internazionale.
Le
operazioni di selezione e di proiezione, entrambe di tipo sottrattivo, possono
essere facilmente realizzate come filtri, la prima sulle righe e la seconda
sulle colonne di una tabella. Esiste un modo grafico assai semplice di definire
un filtro, che consiste nell’usare lo stesso schema descrittivo tabellare, per
la proiezione marcando le colonne da conservare e per la selezione inserendovi
la condizione di selezione eventualmente operante sull’attributo
corrispondente. Le operazioni di join vengono invece rappresentate
graficamente, collegando (come nello schema rappresentativo del modello
entity-relationship) le tabelle coinvolte e sottintendendo che la condizione di
join consiste nell’uguaglianza fra un determinato attributo dell’una e un determinato
attributo dell’altra, attributi che possono essere specificati a parte.
Questo
tipo di query è detto Query By Example (QBE).
L’altra
modalità consiste nell’enunciare le operazioni da compiere in una istruzione,
scritta in un linguaggio codificato detto SQL (Structured Query
Language). Per risparmiare la fatica di apprendere lo SQL, molti DBMS
possiedono dei generatori di query di maggiore o minore complessità e
flessibilità.
A
titolo puramente di esempio, supponiamo di voler elencare i libri del nostro
database accompagnati dal relativo autore. Per semplicità supporremo che nella
nostra biblioteca non vi siano omonimi, di modo che il campo cognome è una
chiave per la tabella autori. Per ogni autore sono stati archiviati almeno i
dati necessari per questa query cioè nome, cognome, data di nascita; per i
libri i campi sono invece titolo, cognome dell’autore (chiave esterna) e
quant’altro desiderato. Supponiamo inoltre di voler ottenere soltanto un elenco
composto da titolo del libro, nome e cognome dell’autore. La query sarà così
formulata:
SELECT
titolo, nome, cognome
FROM
autori, libri
WHERE
cognome = autore
L’ultimo
rigo specifica la condizione di join: si otterranno solo tuple in cui
l’attributo autore della tabella libri sia uguale all’attributo cognome della
tabella autori. Il secondo rigo specifica le tabelle utilizzate per il join. Il
primo rigo specifica una proiezione: nel risultato non verranno mostrati
tuttigli attributi ma solo quelli indicati.
Le
parole SELECT, FROM, WHERE sono specifiche del linguaggio SQL e indicano le
diverse parti dell’istruzione, che viene così ad essere formata da “clausole”
distinte che noi per comodità abbiamo indicato rispetto alle posizioni.
Una
selezione destinata a produrre un elenco degli autori del XX secolo è così
definita
SELECT
*
FROM
autori
WHERE
data-di-nascita successiva 1/1/1900
La
condizione di selezione è descritta nell’ultimo rigo (clausola WHERE), il
secondo (clausola FROM) elenca le tabelle utilizzate, una sola in questo
esempio, il primo (clausola SELECT) dovrebbe descrivere le proiezioni
richieste, in questo caso assenti e quindi rappresentate da un * che significa
“tutti gli attributi”.
Con
una sola istruzione si possono compiere molte operazioni contemporaneamente:
SELECT
titolo, nome, cognome
FROM
autori, libri
WHERE
cognome = autore AND data-di-nascita successiva 1/1/1900
che
combina le due query precedenti, unificandone le condizioni (una di join e una
di selezione) nella clausola WHERE, qui composta da due condizioni distinte, di
cui è richiesto il verificarsi congiunto mediante il connettore logico AND.
Vediamo
il modello logico dei dati nell’esempio delle delibere. Applicando le regole
sopra descritte si ottengono le tabelle seguenti.
Tabella Delibere
Attributo Dominio
Numero Numero
intero (assegnato automaticamente) –
chiave
Titolo Testo
Oggetto Testo
(standardizzato) – Valori multipli
Tabella
Consiglieri
Attributo Dominio
Numero Numero
intero (assegnato automaticamente)
Nome Testo
Affiliazione Testo
(standardizzato)
Professione Testo
(standardizzato)
Tabella
Votazioni
Attributo Dominio
Numero Numero
intero (assegnato automaticamente)
Data Data
Risultato Coppia
di numeri (a favore/contrari)
Presidente Numero
(equivale alla relazione 1-N è presieduta da)
Delibera Numero
(equivale alla relazione 1-1 vota la delibera)
Tabella
Proponenti
Attributo Dominio
Delibera Numero
Consigliere Numero
La coppia (delibera x, consigliere y) è presente in
questa tabella se la delibera x è stata proposta dal consigliere y.
Tabella
Votanti
Attributo Dominio
Consigliere Numero
Votazione Numero
La coppia (consigliere x, votazione y) è presente in
questa tabella se il consigliere x ha votato nella votazione y.
6.
Forme normali.
Normalizzazione
Le
operazioni sulle tabelle, le query e, in generale, la corretta operatività di
un DBMS è assicurata soltanto se si rispettano alcune regole di progettazione
che conferiscono al database determinate proprietà di regolarità.
Una
tabella è in prima forma normale (1NF) se
·
tutti i suoi campi sono atomici,
cioè non ulteriormente decomponibili;
·
ogni campo contiene un
solo dato
In altri termini, non sono
ammessi né sottocampi né campi multipli.
La
regolarità consiste nel fatto che vi è certezza sul contenuto di un campo: un
solo dato. Il trattamento di sue
suddivisioni (sottocampi o componenti singole di un campo multiplo) non
potrebbe essere definito all’interno dello schema progettuale a meno di non
introdurre una sorta di indice di posizione, che non ha alcun collegamento con
la natura del problema (spesso, infatti, i “sottocomponenti” sono in ordine
casuale o imprecisato).
Il
modello logico della tabella delle delibere sopra descritto ha la tabella Delibere
che non è 1NF in quanto presenta campi multipli. Lo si può ricondurre a 1NF
introducendo una tabella “Oggetti delle delibere” ed eliminando l’attributo
oggetto dalla tabella delibera. Si dovrà poi istituire una relazione fra le
delibere e gli oggetti.
Si
ottengono così le seguenti modifiche:
Tabella Delibere (modificata)
Attributo Dominio
Numero Numero
intero (assegnato automaticamente) – chiave
Titolo Testo
(di lunghezza variabile)
Tabella
Oggetti (nuova)
Attributo Dominio
Numero Numero
intero (assegnato automaticamente) – chiave
Descrizione Testo
Tabella
Oggetti-Delibere (nuova)
Attributo Dominio
Delibera Numero
Oggetto Numero
La coppia (delibera x, oggetto y) è presente in questa
tabella se la delibera x ha oggetto y.
Le
altre tabelle restano invariate.
Un
database con tutte tabelle in prima forma normale, presenta, di solito, un
elevato numero di ripetizioni. Ad esempio, tutti i valori degli attributi
collegati o dipendenti da un altro sono ripetuti più volte senza aggiungere informazione.
Supponiamo, ad esempio, di considerare nel nostro esempio bibliografico la
tabella autori, nel caso in cui vi sia più di un autore, inserendo i dati di
ciascuno. Se fra questi dati c’è anche l’anno di nascita, esso sarà ripetuto
ogni volta che compare (in gruppi diversi) la stessa persona, essendo la data
di nascita sempre la stessa, senza però aggiungere informazione. Un database in
prima forma normale presenta quasi sempre questo tipo di ridondanze, dovuta
alla dipendenza funzionale di un attributo da un altro, cioè al fatto
che ad ogni valore del secondo (il nome di una persona) risulta univocamente
assegnato un valore del primo (l’anno di nascita).
Ogni relazione uno-a-uno
stabilisce una doppia dipendenza funzionale, nei due sensi; una relazione
uno-a-molti stabilisce una dipendenza funzionale (il valore dal lato uno è
funzionalmente dipendente da ciascuno dei corrispondenti dal lato molti); una
relazione molti-a-molti non stabilisce dipendenze funzionali.
Si
può decomporre una tabella senza perdita di informazione se l’operazione
inversa, effettuata mediante un join, non produce tuple aggiuntive.
Nell’esempio
precedente, la tabella contenente i nomi degli autori e le rispettive date di
nascita può essere decomposta, senza perdita di informazione, in due tabelle
una con i soli nomi degli autori e una con il nome di ciascuno e il relativo
anno di nascita, che così compare una sola volta in corrispondenza dell’unica
comparsa del nome. La tabella originaria può essere ricomposta mediante un join
delle due nuove tabelle, combinando gli elementi che hanno lo stesso nome.
|
Rossi |
1970 |
Verdi |
1975 |
|
Rossi |
Verdi |
|
Rossi |
1970 |
|
Rossi |
1970 |
Neri |
1960 |
® |
Rossi |
Neri |
+ |
Neri |
1960 |
|
Neri |
1960 |
Verdi |
1975 |
|
Neri |
Verdi |
|
Verdi |
1975 |
|
… |
… |
… |
… |
|
|
|
|
|
|
Una
tabella è in seconda forma normale (2NF) se è in prima forma
normale e tutti i suoi attributi dipendono dalla chiave, cioè se non possiede
attributi funzionalmente dipendenti da una sua parte. Nell’esempio precedente,
la chiave è costituita dai due nomi degli autori, e l’anno di nascita è
funzionalmente dipendente da un solo nome, parte della chiave.
Per ricondurre una tabella
a essere 2NF si attua una decomposizione:
gli attributi che dipendono funzionalmente da una parte della chiave
vengono messi in una tabella separata insieme a questa parte della chiave, come
nell’esempio precedente, e sono rimossi dalla tabella originale, in cui invece
rimane la parte della chiave che funge da chiave esterna per la nuova tabella
creata. Nella tabella dell’esempio precedente, la chiave della tabella è
formata dai due cognomi; l’anno, che è l’attributo funzionalmente dipendente da
uno dei due cognomi, tolte dalla tabella ed è messo in un’altra tabella assieme
al cognome (parte della chiave da cui esso dipende). Uno dei cognomi, rimasto
nella tabella principale, è chiave esterna per la nuova tabella creata.
Applicando questo
procedimento di decomposizione quante volte è necessario, nell’eventualità che
vi siano più dipendenze funzionali, si perviene a una serie di tabelle tutte
2NF.
Il
vantaggio delle tabelle 2NF è che evitano ridondanza di informazione e
incongruenze fra dati analoghi che vengono standardizzati (l’anno di nascita,
ad esempio, è scritto sempre nello stesso modo e non 1990, ’90, 90). Questo
secondo aspetto è particolarmente importante, tanto che proprio per questo
scopo alcuni campi vengono codificati, viene cioè introdotta volontariamente
una dipendenza funzionale fra i dati per standardizzarne la classificazione
mediante un codice, la cui descrizione in chiaro è data da una tabella a parte.
La
decomposizione così definita ha le caratteristiche di non perdere informazione
e di conservare le dipendenze funzionali, trasformando in una relazione quelle
parziali.
La
tabella usata nell’esempio precedente si basa sull’ipotesi che essa sia stata
definita in relazione a un problema per il quale la coppia (Rossi - Verdi) ha
un significato diverso dalla coppia (Verdi – Rossi). In questo caso si tratta
soltanto di un esempio illustrativo del metodo di decomposizione per ricondurre
la tabella a 2NF, ma in un caso reale sarebbe sensato chiedersi se questa
ipotesi è realistica: si possono facilmente immaginare situazioni in cui lo è e
altre in cui non lo è affatto. Naturalmente, in un problema reale, il processo
sarebbe partito dalla realtà per poi definire il modello, anziché inventare un
problema per giustificare una tabella esemplificativa. Tutto ciò per
sottolineare come determinate valutazioni, quale quella appena esposta, possano
trovare risposta soltanto tornando al caso reale che il modello vuol
rappresentare.
Nell’esempio
delle delibere, tutte le tabelle sono 2NF e quindi non necessiterebbe di
ulteriori manipolazioni. Può tuttavia essere consigliabile codificare gli
elementi fissi per evitare errori di digitazione o registrazioni non
standardizzate, modificando la tabella consiglieri e creando due nuove tabelle.
Tabella
Consiglieri
Attributo Dominio
Numero Numero
intero (assegnato automaticamente) – chiave
Nome Testo
Affiliazione Numero
(o sigla)
Professione Numero
(o sigla)
Tabella
Affiliazioni
Attributo Dominio
Descrizione Testo
Tabella
Professioni
Attributo Dominio
Codice Numero
(o sigla) ) – chiave
Descrizione Testo
In
una tabella 2NF possono sussistere attributi dipendenti oltre che dalla chiave
anche da altri attributi, a loro volta dipendenti dalla chiave: possono cioè
esistere dipendenze transitive. Supponiamo, ad esempio, di aver archiviato nel
nostro database autori il nome, la data (completa) di nascita e il segno
zodiacale. Questa tabella è 2NF perché tutti gli attributi dipendono dalla
chiave (il nome) ma il segno zodiacale è dipendente dall’attributo data di
nascita e quindi transitivamente dipendente dalla chiave.
Una
tabella si dice in terza forma normale (3NF) se non sono presenti dipendenze
transitive del tipo sopra definito. Una tabella 2NF può essere riportata a 3NF
ponendo gli attributi dipendenti funzionalmente da un altro attributo in una
tabella separata: nell’esempio, ponendo in una tabella separata la data di
nascita e il segno zodiacale.
La
normalizzazione può essere ancora spinta ulteriormente, ma nei casi pratici è
in genere sufficiente fermarsi alla 3NF o alla 2NF soltanto.
La
trascrizione della descrizione del database nel linguaggio di descrizione dati
tipico del DBMS utilizzato di questo si può, come già detto, quasi sempre
evitare, ricorrendo a un’interfaccia utente per la creazione delle tabelle,
nella quale si devono inserire le informazioni relative a ciascuna adattando i
domini degli attributi ai tipi di dati previsti dal DBMS usato.
Quando
ciò non è possibile, occorre creare il comando o meglio la sequenza di comandi
(detta script) necessari per tale operazione.
A titolo di curiosità si riporta lo script SQL da
usare per creare le tabelle Delibere, Consiglieri e Votazioni usando il comando
CREATE TABLE che ha appunto questa funzione. Come già detto, il linguaggio SQL
è, con qualche variante “dialettale”, uno standard internazionale (ISO/IEC
9075:1992), chiamato SQL92 ed è disponibile per quasi tutti i DBMS relazionali
(RDBMS, Relational DBMS).
CREATE
TABLE delibere (
numero int4,
titolo text);
CREATE
TABLE consiglieri (
numero int4,
nome text,
affiliazione int4,
professione int4);
CREATE
TABLE votazioni (
numero int4,
data date,
favorevoli int4,
contrari int4,
presidente int4,
delibera int4);
CREATE
TABLE oggetti (
numero int4,
descrizione text);
CREATE
TABLE oggetti_delibere (
oggetto int4,
delibera int4);
CREATE
TABLE affiliazioni (
codice int4,
descrizione text);
CREATE
TABLE professione (
codice int4,
descrizione text);
CREATE
TABLE proponenti (
delibera int4,
consigliere int4);
CREATE
TABLE votanti (
consigliere int4,
votazione int4);
Il codice int4 designa un numero intero, usato per i
codici e per i progressivi di sistema. Si noti che non essendo disponibile un
tipo dati “coppia di numeri” è indispensabile spezzare l’attributo “risultato”
della votazione in “favorevoli” e “contrari”.
Nella fase di creazione si dovrebbe inoltre specificare i campi usati
come chiave, utilizzando apposite qualificazioni del linguaggio SQL.
Si elencano di seguito alcuni manuali o raccolte di
saggi sull’argomento specificamente orientati alle problematiche storiche e
archeologiche, segnalando che quelli in lingua inglese sono in generale più
approfonditi e dettagliati e sono quindi da preferire. Su quelli italiani può
essere interessante la problematica metodologica o, come nel caso del volume di
D’Andria, la trattazione del caso studiato.
•
Moscati, P. Archeologia e Calcolatori Giunti, Firenze 1987
•
Mawdsley, E. – Munck, T. Computing for historians. An introductory
guide Manchester University Press, Manchester 1993. ISBN 0-7190-3548-1
•
Greenstein D. I. A Historian’s Guide to Computing Oxford
University Press, Oxford 1994. ISBN 0-19-823521-6
•
Soldani S. – Tomassini L. (a cura di) Storia e Computer. Alla ricerca
del passato con l’informatica Bruno
Mondadori, Milano 1996. ISBN 88-424-9317-1
•
Harvey C. – Press J. Databases in Historical Research Macmillan
Press Ltd., Houndmills, Basingstoke and London 1996. ISBN 0-333-56844-3
•
Niccolucci, F. Dal database all’ipertesto. Applicazioni
dell’informatica ai dati storici e territoriali Centro 2P, Firenze 1997
•
D’Andria,
F. (a cura di) Metodologie di catalogazione dei beni archeologici
Martano - Edipuglia, Lecce - Bari 1997
•
Townsend,
S. – Chappel, C. – Strujvé, O. Digitising
History. A Guide to Creating Digital Resources from Historical Documents (AHDS,
History Data Services). Oxbow Books, Oxford 1999. ISBN 1-900188-91-0