Cos'è l'Eliminazione delle Tabelle?
L'idea di base dietro all'Eliminazione delle Tabelle è la seguente: a volte è possibile risolvere una query senza accedere affatto ad alcune delle tabelle a cui si riferisce. E' possibile inventare molti casi di questo tipo, ma l'Eliminazione delle Tabelle è stata pensata solo per una certa classe di costrutti SQL che a volte si scrivono quando si lavora su dati altamente relazionali.
Le query di esempio sono state sviluppate seguento il Modello ad Ancore (Ancor Modeling), una tecnica che porta la normalizzazione all'estremo. Le slide sul sito del Modello ad Ancore spiegano approfonditamente il Modello ad Ancore e i suoi meriti, ma la parte importante per l'Eliminazione delle Tabelle può essere mostrata con un esempio.
Supponiamo che il database contenga informazioni sugli attori, con i loro nomi, compleanni e voti, dove i voti possono cambiare nel tempo.
Secondo il Modello ad Ancore, ogni attributo dovrebbe andare in una tabella a sé stante:
- La tabella 'ancora' che ha solo una sintetica chiave primaria:
create table ac_anchor(AC_ID int primary key);
- una tabella per l'attributo 'name':
create table ac_name(AC_ID int, ACNAM_name char(N), primary key(AC_ID));
- una tabella per l'attributo 'birthdate':
create table ac_dob(AC_ID int, ACDOB_birthdate date, primary key(AC_ID));
- una tabella per l'attributo 'rating', che è storicizzata:
create table ac_rating(AC_ID int, ACRAT_rating int, ACRAT_fromdate date, primary key(AC_ID, ACRAT_fromdate));
Con questo approccio diventa facile aggiungere/modificare/rimuovere attributi, ma a costo di un'ulteriore complessità nell'interrogazione dei dati: per poter rispondere alle domande più semplici sugli attori e i loro voti attuali, occorre scrivere delle Outer Join:
Mostra gli attori, con i loro nomi e i voti attuali:
select ac_anchor.AC_ID, ACNAM_Name, ACDOB_birthdate, ACRAT_rating from ac_anchor left join ac_name on ac_anchor.AC_ID=ac_name.AC_ID left join ac_dob on ac_anchor.AC_ID=ac_dob.AC_ID left join ac_rating on (ac_anchor.AC_ID=ac_rating.AC_ID and ac_rating.ACRAT_fromdate = (select max(sub.ACRAT_fromdate) from ac_rating sub where sub.AC_ID = ac_rating.AC_ID))
Non vogliamo scrivere delle Join ogni volta che abbiamo bisogno di accedere alle proprietà di un attore, perciò creiamo una vista:
create view actors as select ac_anchor.AC_ID, ACNAM_Name, ACDOB_birthdate, ACRAT_rating from <see the select above>
Questo ci permette di accedere ai dati come se fossero registrati in modo normale:
select ACRAT_rating from actors where ACNAM_name='Gary Oldman'
E a questo punto c'è bisogno dell'Eliminazione delle Tabelle.
See also
- Questa pagina si basa sul seguente post a proposito della Table Elimination: http://s.petrunia.net/blog/?p=58