2001/02 Lezione N. 16 Organizzazione di banche dati Ordinamento

2001/02
Lezione N. 16
Organizzazione di banche dati
Meccanismi di indicizzazione e strutture dati. I meccanismi di indicizzazione e le strutture dati utilizzate per la
rappresentazione delle tabelle e degli indici determinano le prestazioni del database, che si misurano in base ai
tempi di inserimento, modifica, cancellazione e consultazione (nel caso migliore, medio e peggiore). Tali tempi
sono espressi come prodotto del numero di accessi necessari ad ultimare l’operazione per il tempo di accesso
unitario (considerato costante per tutti i record). In genere, il numero di accessi dipende dal numero di record nella
tabella (N) e dalle dimensioni della struttura dati dell’indice. Altra caratteristica importante è l’eventuale necessità di
riordinare periodicamente i dati archiviati. Nel seguito non considereremo i tempi di modifica di un record,
osservando che la modifica comporta una ricerca preventiva del record, alla cui complessità occorre aggiungere il
tempo effettivo di modifica. Per valutare quest’ultimo occorre distinguere due casi: se la modifica non coinvolge i
campi chiave, il tempo è unitario (o costante); se la modifica coinvolge i campi chiave può essere necessaria una
riorganizzazione dell’indice la cui complessità è la somma delle complessità di una cancellazione e di una
inserzione.
Tabelle non ordinate. Non necessitano di alcun indice, né di alcuna riorganizzazione. Il tempo di inserimento di un
record è unitario, mentre la modalità di ricerca è sequenziale. Pertanto il tempo di consultazione è 1 nel caso
migliore, N nel caso peggiore, N/2 in media. I tempi di cancellazione e modifica sono dominati dal tempo di ricerca.
Ogni tabella è fisicamente ordinata in base all’indice relativo di inserimento, che ne costituisce una chiave primaria.
Se la chiave di ricerca è l’indice relativo la consultazione avviene per accesso diretto del record associato alla riga
prescelta della tabella. Il tempo di consultazione diviene quindi unitario, come quello di aggiornamento.
Il vantaggio principale delle tabelle non ordinate è la semplicità. Lo svantaggio principale è il tempo di
consultazione elevato, o il vincolo ad utilizzare l’indice relativo come chiave per effettuare ricerche efficienti.
Tabelle con indici. L’uso di indici consente di superare i limiti delle tabelle non ordinate. Infatti, creando un indice
ordinato in base ad un campo chiave di una tabella si possono effettuare ricerche ordinate sulla tabella senza
modificarne direttamente la rappresentazione. Inoltre, per una stessa tabella possono essere creati indici ordinati in
base a chiavi diverse, consentendo quindi di effettuare ricerche efficienti secondo diversi criteri. Gli indici possono
essere ordinati fisicamente o logicamente. Nel primo caso gli elementi dell’indice possono essere visti a loro volta
come le righe di una tabella la cui posizione fisica rappresenta l’ordine. Nel secondo caso gli elementi dell’indice
sono fisicamente disposti come i record (non ordinati) della tabella a cui puntano, ma sistemi di puntatori creano un
ordine logico diverso da quello fisico.
Ordinamento fisico
Indici ordinati fisicamente. Se l’indice è ordinato fisicamente in base ad una chiave della tabella, la ricerca
(secondo tale chiave) può avvenire in modo sequenziale (con le stesse prestazioni indicate per le tabelle non
ordinate) o dicotomico. La ricerca dicotomica ad ogni accesso dimezza il numero di record su cui continuare la
ricerca. Il tempo di consultazione nel caso peggiore si riduce così a log2(N+1), quello medio a log2(N+1)-1
(approssimati per eccesso all’intero più vicino). Lo svantaggio principale dell’ordinamento fisico è che per ogni
nuovo inserimento occorre riordinare l’indice (cioè inserire il nuovo elemento dell’indice nella posizione giusta).
Questo comporta, per ogni nuovo inserimento, una ricerca e lo spostamento di tutti gli elementi dell’indice in
posizioni successive a quella di inserimento (N/2 in media), per una complessità totale media di log2(N)+N/2. Per
ovviare a questa inefficienza si può utilizzare un indice provvisorio disordinato per i record di recente inserzione,
effettuando riordinamenti periodici dell’intero indice.
Ordinamento logico
Indici ordinati logicamente: lista ordinata. Ogni elemento dell’indice contiene un campo che punta all’indirizzo
relativo dell’elemento che segue nell’ordinamento logico. L’ordine logico non richiede riorganizzazioni per essere
mantenuto a seguito di un nuovo inserimento. Individuata la posizione del record da inserire, è sufficiente
aggiornare i puntatori dell’elemento precedente e dell’elemento stesso (operazioni di complessità costante).
Considerazioni analoghe valgono per la cancellazione di un record. Lo svantaggio è che la ricerca può essere
effettuata solo in modo sequenziale, seguendo la lista ordinata a partire da un puntatore al primo elemento. Le liste
ordinate sono però notevolmente più efficienti delle tabelle non ordinate nel caso di accessi multipli finalizzati, ad
esempio, alla stampa in ordine di tutti i record del database (Es: stampa di un elenco telefonico secondo l’ordine
alfabetico degli abbonati). In caso di tabelle non ordinate questo comporterebbe N accessi sequenziali di
2
complessità media N/2 ciascuno (tempo complessivo N /2) in caso di liste ordinate l’operazione richiede solo la
scansione dell’indice (tempo complessivo N).
Indici ordinati logicamente: albero binario. Un albero binario è un albero i cui rami si biforcano ripetutamente
dalla radice fino alle foglie. Ogni elemento dell’indice è un nodo dell’albero, cioè un punto di biforcazione o una
foglia. Ad ogni elemento sono associati due puntatori (campi) che puntano agli indirizzi relativi di altri due nodi (detti
figli). Il nodo radice non è puntato da nessun altro nodo, i nodi foglia non puntano a nessun altro nodo. Tutti i
restanti nodi puntano ad uno o due nodi figli e sono puntati da un solo nodo padre. Chiamiamo destro e sinistro i
due figli di uno stesso nodo. Perché l’albero binario rappresenti un ordinamento logico (crescente) occorre che
siano soddisfatte le seguenti condizioni: ogni figlio destro deve avere la chiave più grande (cioè successiva
nell’ordinamento) di quella del rispettivo nodo padre; ogni figlio sinistro deve avere la chiave più piccola (cioè
precedente nell’ordinamento) di quella del rispettivo nodo padre. La profondità di un albero binario bilanciato è
log2(N). Gli alberi binari si prestano ad effettuare ricerche dicotomiche a partire dalla radice. Il tempo di
consultazione è 1 nel caso migliore (il nodo cercato è la radice), log2(N) nel caso peggiore (il nodo cercato è una
foglia), log2(N)-1 nel caso medio. L’inserimento crea sempre una nuova foglia, e comporta una ricerca binaria di
complessità logaritmica. Meritano attenzione gli algoritmi di cancellazione di un record (complessità logaritmica) e
di stampa ordinata di tutti i record (complessità lineare). Si veda Boni, pag. 420 e seguenti.
Ref: Boni Cap. 7.407-430