LA PROGETTAZIONE DELLE BASI DI DATI: IL DISEGNO LOGICO,
UN'ATTIVITà CHE MERITA PIù ATTENZIONE
Quando si parla di progettazione di una base di dati ci si
riferisce ad un insieme di attività, più o meno strutturate e
formalizzate, che possono essere raggruppate in tre fasi:
- definizione del modello concettuale
- progettazione logica
- progettazione fisica.
Scopo della costruzione del modello concettuale è quello di
tradurre la parte del patrimonio dati aziendale che si intende
automatizzare in una architettura di base di dati che la descriva
in modo ottimale dal punto di vista semantico.
Nel modello concettuale si cerca dunque di costruire uno schema,
privo di imperfezioni logiche e di ridondanza fra dati, capace di
rappresentare tutti gli aspetti della realtà esaminata.
A questo punto, però, non tutti i giochi sono fatti, nel senso
che non è sempre possibile tradurre immediatamente le relazioni
dello schema concettuale in tabelle (o record, o segmenti, ...)
di un particolare DBMS. Un modello che funziona sulla carta,
infatti, non è detto che funzioni in modo efficiente una volta
riportato nell'ambito di un sistema informatico, in quanto
sistema a risorse limitate sia dal punto di vista spaziale
(capacità di memorizzazione) che temporale (velocità di
esecuzione).
Il modello concettuale va dunque rivisto ed eventualmente
ottimizzato alla luce dei limiti citati, e dell'adeguatezza di
fornire risposte in termini accettabili alle applicazioni
previste.
Ma c'è un altro motivo di fondo che rende necessario il
passaggio da un ambiente ( e da uno schema) concettuale ad un
ambiente logico.
Ogni DBMS, infatti, ha delle caratteristiche che lo rendono
particolare (quelle di un DBMS gerarchico sono differenti da
quelle di un DBMS reticolare o relazionale).
I dati che fanno parte dello schema concettuale possono venire
utilizzati in diversi ambienti logici (ad es. DL/1, DB2, DBIII,
...). Ogni dato dello schema concettuale può essere quindi
espresso in formati diversi, ed analogamente ogni entità dello
schema concettuale viene tradotta a seconda del DBMS utilizzato
per gestirla.
La progettazione logica, quindi, in prima approssimazione,
potrebbe essere pensata come un'operazione di "conversione" che
tende a tradurre il modello concettuale dei dati sulla base di
vincoli strutturali, di formato e di altro tipo che sono tipici
di ogni DBMS. In realtà, se condotta ed eseguita in modo
corretto, questa attività, che rappresenta il primo momento in
cui le staff tecniche prendono visione dei nuovi progetti, può
diventare un importante momento di verifica durante il ciclo di
progettazione delle applicazioni.
ESAME CONGIUNTO DI DATI E PROCESSI
Nella sua formulazione più estesa, l'attività prevede l'esame
congiunto, da parte del gruppo di progetto e del DBA, della
documentazione concettuale prodotta, in termini sia di dati che
di processi. L'obiettivo è progettare una base di dati
"verificata", che aderisca cioè in modo efficiente ed efficace
alle esigenze funzionali definite dall'utente. Occorre quindi
controllare innanzitutto che:
- tutti i dati previsti dalle applicazioni siano stati previsti
anche nelle entità dello schema concettuale
- le applicazioni non violino i vincoli di integrità
referenziale previsti nello schema concettuale (ad esempio, che
non venga cancellato un fornitore dall'entità "fornitori"
senza prima controllare se esistano ordini per quel fornitore
nell'entità "ordini"). Come è noto i sistemi relazionali, ed
in particolare il DB2, gestiscono i vincoli di referential
integrity; in alcuni casi è quindi sufficiente dichiarare tali
vincoli al sistema
Inoltre, l'esame dettagliato delle funzioni consente di
evidenziare in anticipo eventuali problemi quali ad esempio la
contesa sui dati e costituisce una base di partenza probante per
effettuare una previsione di carico (performance prediction e
capacity planning).
Questa attività può quindi servire a:
- determinare in linea di massima gli statement SQL necessari
all'applicazione
- fornire input per progettare più accuratamente le basi di dati
(opportunità di indici, di partizionamento, di ordinamento
fisico ecc...)
- fornire indicazioni per il disegno delle applicazioni
- definire gli "schemi degli accessi" ovvero una descrizione
degli statement di manipolazione dei dati utilizzati dalle
singole funzioni
Grazie alla potenza del linguaggio SQL, che consente di esprimere
le richieste di accesso in modo non procedurale, la
determinazione degli statement necessari per l'accesso ai dati è
molto meno complessa di quanto non avvenga in ambiente
tradizionale (DL/1, ....).
La determinazione degli statement ha un impatto significativo
sulla progettazione delle basi di dati, in quanto permette di
evidenziare con precisione, e in anticipo, le criticità
possibili a fronte di una data struttura, e di conseguenza i
correttivi da applicare.
ANALISI DELLE ENTITà
Questa fase prende in esame le entità ed i legami di integrità
referenziale prodotti durante la progettazione del modello
concettuale.
Per ogni entità occorre garantire che la chiave primaria non
ammetta valori duplicati (entity integrity) e quindi, in ambiente
DB2, si dovrà documentare la necessità di definire su di essa
un indice unique. L'indice unique è l'unico modo per garantire
l'univocità dei valori di un attributo all'interno di
un'entità, e dovrebbe essere definito anche per tutte le
eventuali chiavi alternative.
Occorrerà documentare , inoltre, la necessità di un indice
"potenziale" per le chiavi esterne di ogni entità in quanto sono
queste che permettono ai vari processi del sistema di "navigare"
fra le entità dello schema.
La definizione di un indice "potenziale" non implica
necessariamente che esso verrà fisicamente definito (il che
dipenderà essenzialmente dall'analisi dei processi e dalla
distribuzione dei valori), bensì si intende documentare il fatto
che su quel insieme di attributi la definizione di un indice può
portare benefici.
Nei DBMS Relazionali la scelta dell'utilizzo di un indice non è
dettata da una richiesta esplicita, bensì è l'ottimizzatore
che, sulla base delle regole su cui è costruito, si assume
l'onere di tale scelta.
I DBMS Relazionali presenti attualmente sul mercato si basano
generalmente su una delle seguenti regole:
- SEMANTIC RULES BASED; è l'espressione semantica del comando
SQL che influenza l'ottimizzatore nelle sue scelte
- STATISTICAL RULES BASED; è l'insieme delle informazioni
statistiche contenute sul catalogo che indirizza la scelta
dell'ottimizzatore
Nel primo caso è il programmatore che valuta l'effettiva
convenienza ad utilizzare un indice e lo comunica al sistema
"costruendo" opportunamente il comando SQL.
L'uso di informazioni statistiche memorizzate sul catalogo ed
aggiornate periodicamente consente al sistema di effettuare
scelte più imparziali e svincola, almeno in prima istanza, il
programmatore da problemi di ottimizzazione.
In ogni caso, comunque, la definizione di un indice in ambiente
relazionale non ne implica necessariamente l'utilizzo da parte
del sistema. La definizione di indici sulle chiavi "potenziali"
deve quindi essere fatta a ragion veduta in base ai seguenti
criteri di valutazione:
- devono esistere dei processi che ne giustifichino l' utilizzo
in termini di accesso, frequenza e priorità
- le richieste di ricerca devono essere puntuali o per scansione
di range
- il numero di valori univoci dell'insieme di attributi su cui
si costruisce l'indice deve essere sufficientemente elevato
- il numero di righe che compongono l'entità deve essere
cospicuo. Non ha senso definire indici (tranne che per
garantire l'univocità dei valori) su tabelle contenenti poche
righe
Si prendano come esempio le entità Cliente ed Ordine legate fra
loro da una relazione uno a molti.
Per quanto riguarda l' entità Cliente avremo :
- un indice unique sulla chiave primaria Cod_cliente
- un indice unique sulla chiave candidata Cod_fiscale
Per quanto riguarda l' entità Ordine avremo :
- un indice unique sulla chiave primaria Num_ordine
- un indice potenziale sulla chiave esterna Cod_cliente_ordine
Occorre inoltre valutare le seguenti implicazioni:
- problemi di prestazione nel caso in cui le operazioni di
manipolazione siano predominanti e prioritarie rispetto a
quelle di ricerca. Per ogni operazione di manipolazione
verrà pagato un costo aggiuntivo in termini di CPU ed I/O
- problemi di concorrenza, in quanto la densità dati per pagina
di un indice è generalmente superiore a quella della parte
dati
- problemi di gestione legati ai costi di manutenzione degli
indici
ANALISI DEI PROCESSI
In questa fase si prendono in esame i processi definiti durante
l' analisi funzionale del sistema.
Per ogni processo si eseguiranno i seguenti passi :
a) verificare che tutte le entità e gli attributi utilizzati
siano stati definiti in modo congruente nel modello dei dati;
b) individuare tutti gli accessi secondari, cioè gli attributi
o insiemi di attributi al di fuori delle chiavi primaria o
esterna o alternativa, e documentare su di essi un indice
"potenziale"
c) individuare e documentare, per ogni entità coinvolta, tutte
le richieste di raggruppamento o ordinamento dei dati al di
fuori della chiave primaria. Si tratta di uno degli elementi
che concorrono alla determinazione dell'insieme di attributi
su cui definire la chiave di ordinamento fisico (indice
cluster)
Ad esempio, se si considera il processo che deve fornire gli
ordini emessi in una precisa data, verrà richiesto un accesso
secondario sull'attributo Data_emissione_ordine, che può essere
preso in considerazione anche come potenziale attributo di
"clusterizzazione".
Dall' analisi di ogni singolo processo si otterrà, inoltre, come
output, uno schema degli accessi dettagliato.
Ogni schema, oltre a contenere informazioni sul modo e sulle
entità alle quali si accede, fornirà informazioni sulla
frequenza di esecuzione del processo (giornaliera e nell'ora di
punta), sulla sua tipologia (sincrona o asincrona), eccetera.
Da questa documentazione, tramite tecniche di PERFORMANCE
PREDICTION, si potrà valutare il peso di ogni singolo processo
ed i consumi dell' intero sistema, oltre a fornire informazioni
sul dimensionamento delle risorse.
Analizzando queste valutazioni si potranno ricavare informazioni
sulla "validità" della base di dati e dei processi definiti, e
di conseguenza riciclare sulla progettazione logica dei dati e
sulla analisi dei processi o passare alla fase di progettazione
fisica.
ANALISI DELLE MATRICI
Dalla documentazione prodotta durante la realizzazione del
modello concettuale dei dati e dell'analisi funzionale possono
essere ottenute varie matrici di associazione. In ambiente CASE
la produzione di tali matrici è sicuramente semplificata.
Le matrici costituiscono uno strumento di verifica di quanto
prodotto nelle precedenti fasi, fornendo una visione globale
delle componenti dati e funzioni del sistema in oggetto.
Le matrici che vengono più comunemente analizzate sono due:
- Matrice Entità / Funzioni
- Matrice Attributi (Entità) / Funzioni
tramite le quali vengono evidenziate le tipologie di accesso alle
entità (o ai singoli attributi) effettuate da ogni funzione.
FIGURA 2
Le matrici descritte possono anche essere prodotte separatamente
per ogni tipologia di operazione (una matrice per l'inserimento,
una per la variazione, ecc.); questo permetterà di analizzare e
documentare in modo più organico l'impatto di ogni singolo tipo
di operazione sul sistema.
Le analisi che potranno essere effettuate sulle matrici sono
essenzialmente di due tipi:
- analisi orizzontale: permette di focalizzare l'attenzione su
una singola funzione, evidenziando le operazioni effettuate su
entità ed attributi
- analisi verticale: focalizza l' attenzione su una singola
entità o sull'insieme dei suoi attributi, evidenziando come
questi vengano manipolati dalle funzioni del sistema
Chiaramente le due tipologie di analisi sono assolutamente
complementari. Attraverso l' analisi delle matrice verranno
evidenziati e documentati i seguenti punti :
a) problemi legati alla concorrenza fra processi
b) problemi legati alle prestazioni (numero di tabelle
coinvolte,....)
c) problemi logici legati al disegno delle funzioni,
ad esempio più funzioni che inseriscono la stessa entità
d) problemi legati alla gestione della integrità referenziale
da parte del DBMS
Per risolvere i problemi documentati in questa fase si può
procedere in due modi:
- utilizzare tecniche di denormalizzazione e scomposizione
- rivedere le funzioni risultate critiche
DENORMALIZZAZIONE
Nella fase di analisi dei dati, e quindi di costruzione dello
schema concettuale dei dati, le attività di "normalizzazione"
operano delle "proiezioni" successive sulle relazioni di partenza
dello schema, allo scopo di ottenere relazioni finali prive di
ridondanze di dati.
Quando però si scende nel dettaglio delle varie funzioni del
sistema può accadere di constatare che gruppi di funzioni
utilizzano frequentemente dati contenuti in relazioni diverse,
che devono essere quindi "unite" per poter fornire il risultato
voluto.
Poiché queste operazioni di JOIN possono comportare un elevato
costo in termini di prestazioni, una soluzione efficace può
essere quella di introdurre delle ridondanze di dati in modo
controllato. Lo svantaggio sostanziale di questa tecnica è
legato alla necessità di propagazione di aggiornamento del dato,
che, oltre a richiedere maggior spazio disco, introduce la
possibilità di avere valori incongruenti fra la struttura
originaria e quella duplicata.
SCOMPOSIZIONE
Nella rappresentazione concettuale dei dati ogni entità ha una
chiave diversa. Non esistono quindi due entità che hanno la
stessa chiave a meno di gerarchie IS-A (ad esempio, le
sottoclassi operai e impiegati appartenenti alla classe
dipendenti). In fase di progettazione logica possono essere
evidenziati queste tipologie di legami.
Un'altra indicazione che perviene dall'analisi concettuale
riguarda l'esistenza di attributi "condizionali" (che possono non
essere valorizzati a fronte di determinate occorrenze
dell'entità). In fase di progettazione logica è necessario
valutare l'opportunità di una scomposizione che introduca una
nuova tabella.
L'ultimo caso riguarda la "scomposizione per trattamento".
All'interno di una entità possono esistere attributi che
vengono gestiti in modo non omogeneo dalle funzioni. Per
ottimizzare le funzioni più frequenti, e quindi prioritarie, una
soluzione è quella di scindere l' entità originale in due
tabelle. Questa tecnica migliora le prestazioni delle funzioni
più frequenti in quanto il numero di dati letti in una pagina è
superiore a quello precedente, ma, come nel caso precedente,
comporta la necessità di tener allineate le due strutture.