Istituto Universitario di Architettura di Venezia
Corso di Diploma in Sistemi Informativi Territoriali (prof.ssa Alberta
Bianchin)
Lezioni ed esercitazioni a cura di Markus M.
Hedorfer
Argomento trattato approfonditamente durante la lezione del 21 aprile 1997.
Relazionare due tabelle tra di loro significa impostare un qualche tipo di collegamento tra due insiemi di dati, organizzati sotto forma di tabella con righe (records) e colonne (campi), in modo tale da poter accedere ai dati archiviati all'interno di una delle due tabelle relazionate a partire dall'altra tabella.
Perché è opportuno fare questo?
Considerando un esempio abbastanza semplice di base di dati tabellare (ispirato agli esempi nel libro Understanding SQL di Elizabeth Lynch, per le coordinate bibliografiche si rimanda alla pagina "Alcuni (pochi) Riferimenti Bibliografici"), una ditta potrebbe archiviare i propri dati sulle vendite e sui venditori in una tabella fatta nel modo seguente.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
In questa tabella, il campo EMPNO riporta un identificatore numerico di un singolo venditore della ditta, per evitare che eventuali casi di omonimia causino problemi nell'attribuzione dei contratti di vendita ai singoli venditori. Il campo SURNAME riporta invece il cognome del venditore. Il campo CUSTNAME riporta il nome della ditta con cui il venditore specificato ha stipulato un contratto di vendita ed il campo AMOUNT riporta l'ammontare, espresso ovviamente in US$, del singolo contratto di vendita.
Come si vede, i quattro venditori della ditta hanno stipulato complessivamente tre contratti, dove però il venditore Smith è stato più bravo dei suoi colleghi Jones, Brown e Gonzalez per quanto riguarda il numero dei contratti. Per quanto riguarda l'ammontare dei contratti, il più bravo è stato Jones. Con la ditta Hi Markets, poi, sono stati stipulati ben due contratti, uno da Smith e l'altro da Gonzalez. Il venditore Brown invece è, con ogni probabilità, vicino al licenziamento in quanto non è riuscito a portare a casa nemmeno un contratto.
Si capisce subito che questo modo di archiviare i propri dati è alcquanto inefficiente perché costringe a ripetere dei dati che potrebbero essere registrati invece una sola volta. Dividendo questa tabella unica in tre tabelle distinte, SALESMEN per i venditori, CUSTOMERS per i clienti e CONTRACTS per i contratti stipulati, il database avrebbe invece il seguente aspetto:
SALESMEN
|
|
|
|
|
|
|
|
|
|
CUSTOMERS
|
|
|
|
|
|
|
|
CONTRACTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Come si vede, l'organizzazione dei dati è diventata più lineare. Non ci sono più né ridondanze né celle vuote. L'unica cosa che resta da fare è mettere opportunamente in comunicazione tra loro queste tre tabelle per poter rispondere a domande come "Con quali ditte Jones ha stipulato dei contratti?", "Quali venditori hanno stipulato dei contratti con la ditta Hi Markets?" oppure "Quale fatturato ha realizzato Smith?"
Considerando le tre tabelle riportate sopra (SALESMEN, CUSTOMERS e CONTRACTS), le relazioni che si devono instaurare riguardano la possibilità di far comunicare tra loro, da un lato, le tabelle SALESMEN e CONTRACTS e, dall'altro lato, le tabelle CUSTOMERS e CONTRACTS. La comunicazione, invece, tra le tabelle SALESMEN e CONTRACTS (che è quella che, in fondo, interessa maggiormente) deve avvenire esclusivamente appoggiandosi alla tabella di 'intermediazione' CONTRACTS. Per comprendere bene questa necessità, è indispensabile introdurre, a livello teorico, una distinzione in diversi tipi di relazionamento.
Le relazioni chiamate solitamente "uno a uno" sono le più semplici. Se, riprendendo l'esempio dei venditori, ogni venditore avesse stipulato un solo contratto, ogni singolo contratto interessasse una sola ditta e ogni ditta fosse interessata da un solo contratto, le tre tabelle potrebbero apparire nel modo seguente.
SALESMEN
|
|
|
|
|
|
|
|
CUSTOMERS
|
|
|
|
|
|
|
|
CONTRACTS
|
|
|
|
|
|
|
|
|
|
|
|
Le tre tabelle potrebbero quindi essere allineate tra di loro senza problemi:
|
|
|
||||||||||||||||||||||||||||||
|
|
|
Ogni riga (record) di ogni tabella corrisponde esattamente ad un record nelle altre due tabelle. Per questo, si preferisce chiamare una relazione di questo tipo con l'espressione intuitiva "uno a uno". A dire il vero, la presenza di una relazione "uno a uno" rivela che, in fondo, non sarebbe neanche necessario suddividere la base di dati in più tabelle. Si potrebbero infatti fondere le tre tabelle in una sola nel modo seguente:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Sarebbe, più o meno, ripristinata la struttura del database considerato all'inizio di questo paragrafo, con la differenza però che i dati presenti qui non hanno né ridondanze né celle vuote. Per stabilire, quindi, se si possono organizzare tutti i dati in una sola tabella o meno, bisognerà sapere con certezza se le eventuali relazioni "uno a uno" rappresentano solamente una situazione particolare o se per definizione ad ogni record delle tabelle corrisponde sempre soltanto un record delle altre tabelle. Nel primo caso (situazione casuale) bisogna suddividere il database in più tabelle, mentre nel secondo caso (situazione sistematica) è opportuno predisporre una sola tabella.
Le relazioni definite con l'espressione "molti a uno", invece, sono quelle più frequenti, soprattutto nei GIS. Considerando ora due delle tre tabelle presentate al paragrafo "Perché Relazionare due Tabelle" (la tabella CONTRACTS e la tabella CUSTOMERS), si nota immediatamente che
Disponendo le due tabelle una accanto all'altra
|
|
||||||||||||||||||||||||
|
|
la relazione è di tipo "uno a uno" solamente considerando i primi tre records della tabella CONTRACTS. La presenza, invece, del quarto record fa sì che ad un record della tabella di destra possa corripondere anche più di un record (molti records) nella tabella di sinistra.
Diventa a questo punto ovvio che per relazionare due tabelle occorre anzitutto stabilire i campi che in entrambe le tabelle fungono da 'intermediari'. Nel caso qui considerato si tratta, nella tabella CONTRACTS del campo CUSTNO e nella tabella CUSTOMERS del campo CUSTNO. È importante comprendere che i due campi CUSTNO nelle due tabelle non sono lo stesso campo, ma due campi ben distinti. Volendo, i due campi potrebbero anche avere nomi diversi. Quando però si imposta un database con tabelle che devono essere relazionate tra di loro, è comunque opportuno chiamarli allo stesso modo per facilitare la lettura e la comprensione delle tabelle e per segnalare in modo chiaro che si tratta di campi destinati e fungere da 'intermediatori'.
In molti software, le procedure di relazionamento consentono poi di creare un ambiente di lavoro tale da dare l'impressione all'utente di lavorare con una sola tabella. Dopo aver eseguito la procedura di relazionamento (che, per esempio, in Arc/Info, si chiama semplicemente RELATE con una serie di parametri), l'ambiente di lavoro può essere rappresentato graficamente nel modo seguente:
CONTRACTS.CUSTNO oo -- 1 CUSTUMERS.CUSTNO
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
L'espressione CONTRACTS.CUSTNO sta per "campo CUSTNO della tabella CONTRACTS" e l'espressione CUSTOMERS.CUSTNO sta per "campo CUSTNO della tabella CUSTOMERS". Il simbolo "oo" sta per "molti", "1" per "uno" e "--" per "relazionamento".
Le relazioni definite con l'espressione "uno a molti" hanno la medesima struttura delle relazioni "molti a uno". L'unica differenza, a livello logico, è che la tabella che era a sinistra si trova ora a destra e viceversa. A livello pratico, invece, le differenze sono più consistenti.
Se il fatto di relazionare una tabella con un'altra viene considerato come una sorta di 'estensione' della tabella di sinistra verso quella di destra (dove, cioè, ogni volta che nella tabella di sinistra si ripete un valore nel campo 'intermediatore' devono essere ripetuti i valori di tutti i campi della tabella di destra), la cosa non funziona più invertendo le parti. A seconda del software di gestione del database di cui si dispone, le soluzioni tecniche sono diverse. Considerando ora le due tabelle SALESMEN e CONTRACTS, per le quali è possibile instaurare una relazione del tipo "uno a molto" (SALESMEN.EMPNO 1 -- oo CONTRACTS.EMPNO) la tabella 'virtuale' risultante potrebbe
Molti altri software, invece, non consentono la creazione di relazioni di tipo "uno a molti" per mantere coerente la struttura tabellare dei dati e per non andare incontro a situazioni troppo problematiche.
Gli stessi problemi si presentano anche quando si tenta di instaurare una relazione di tipo "molti a molti" complicando tuttavia ulteriormente la questione. I dati sui venditori ed i contratti con i clienti, a ben vedere, necessiterebbe proprio una relazione di questo tipo.
Invece di definire direttamente una relazione "molti a molti", si procede quindi a definire due relazioni di tipo "molti a uno":
CONTRACTS.EMPNO oo -- 1 SALESMEN.EMPNO
e
CONTRACTS.CUSTNO oo -- 1 CUSTOMERS.CUSTNO
ottenendo una tabella 'virtuale' fatta nel modo seguente:
|
|
|
|
|
||
|
|
|
|
|
||
|
|
|
|
|
||
|
|
|
|
|
||
|
|
|
|
|
Il venditore Brown, ovviamente, non compare in questa rappresentazione sebbene sia presente nella tabella SALESMEN.
Come si è già accennato prima, le tecniche con cui si instaurano delle relazioni tra più tabelle variano moltissimo da un software all'altro. Per ora, tuttavia, può bastare considerare solamente i due software GIS con cui, nell'ambito del corso di cartografia numerica, si ha maggiormente a che fare.
I relazionamenti di Arc/Info vengono costruiti con il comando RELATE che ha due opzioni: ADD (aggiungi) e DROP (rimuovi). Un singolo relazionamento viene identificato con un nome che l'utente deve fornire al momento della sua costruzione. L'utente deve anche fornire il nome della tabella di destra, il nome del campo che funge da 'intermediatore' nella tabella di destra e il nome del campo che funge da 'intermediatore' nella tabella di sinistra. Non è invece necessario specificare il nome della tabella di sinistra. Ciò consente di considerare dinamicamente diverse tabelle 'di sinistra' - l'importante è che tutte le tabelle 'di sinistra' con cui si intende utilizzare un unico relazionamento abbiano un campo con il nome specificato durante la procedura di costruzione del relazionamento. Poi, l'utente dovrà fornire anche delle informazioni sul tipo di tabella interessato (se è nel formato interno di Arc/Info o se riguarda un database esterno), sulle modalità con cui accedere ai dati relazionati e se le tabelle relazionate devono essere aperte in sola lettura, in scrittura, e così via.
La sintassi del comando RELATE per aggiungere un relazionamento è in Arc/Info
che per le due relazioni riportate sopra si traduce in
Una volta instaurati questi due relazionamenti, è necessario aprire una tabella valida per il relazionamento (per il relazionamento salesmen una tabella che contiene un campo EMPNO e per il relazionamento customers una tabella che contiene un campo CUSTNO). Per poi accedere ai campi delle tabelle relazionate, ci si comporta come se i campi delle tabelle relazionate facessero effettivamente parte della tabella aperta, con la differenza che i nomi di questi campi dovranno essere preceduti dal nome del relazionamento e da due barre ("//"). La tabella CONTRACTS apparirà quindi all'utente nel modo seguente:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Infine, per rimuovere i due relazionamenti si digita semplicemente
dopodiché ogni collegamento verso le tabelle SALESMEN e CUSTOMERS sarà rimosso.
Esiste poi, in Arc/Info, anche il comando JOINITEM che effettua un relazionamento di tipo fisico unendo effettivamente le tabelle relazionate in una sola. La sintassi del comando JOINITEM è
joinitem <tabella_sx> <tabella_dx> <nuova_tabella> <campo> <campo_iniziale> <modalità>
dove l'opzione <nuova_tabella> permette di specificare il nome della nuova tabella che si intende creare, <campo> indica il nome del campo 'intermediatore' che questa volta deve sì avere lo stesso nome in entrambe le tabelle, e <campo_iniziale> specifica il nome del campo nella tabella di sinistra dopo il quale devono essere posizionati i campi aggiuntivi provenienti dalla tabella di sinistra. I due relazionamenti instaurati prima con il comando RELATE, verrebbero creati con il comando JOINITEM nel modo seguente:
Dopodiché, la nuova tabella CONTRACTS_2 avrebbe l'aspetto seguente:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
E la tabella finale CONTRACTS_3 avrebbe questo aspetto:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Per rimuovere i due relazionamenti creati con il comando JOINITEM è quindi necessario cancellare dal disco fisso le due tabelle CONTRACTS_2 e CONTRACTS_3. È anche importante sapere che, una volta creata una nuova tabella con questo comando, non esiste più alcun collegamento dinamico con le tre tabelle di partenza CONTRACTS, SALESMEN e CUSTOMERS. Per cui eventuali modifiche su queste tre tabelle, a differenza dei relazionamenti con il comando RELATE, non avranno alcun effetto sulle nuove tabelle CONTRACTS_2 e CONTRACTS_3.
Vista la notevole differenza tra i due comandi, si prefereisce, nel gergo degli utenti di Arc/Info, si preferisce chiamare relate un relazionamento creato con il comando RELATE e join un relazionamento creato con il comando JOINITEM.
Anche il software ArcView dispone di due ambienti di relazionamento diversi che, tuttavia, si distinguono in alcuni aspetti da quelli di Arc/Info.
Il comando LINK crea semplicemente un collegamento dinamico tra due tabelle. Ciò vuol dire che, quando sono selezionati uno o più records in una delle due tabelle relazionate, risulteranno essere selezionati anche tutti i records corrispondenti nell'altra tabella. Non esiste invece alcun modo per accedere direttamente ai valori nei campi della tabella di destra. In altre parole: non verrà creata alcuna tabella 'virtuale'. Per instaurare, in ArcView, un link è necessario
Invece per rimuovere i links creati bisogna
Attenzione però: in ArcView non è possibile rimuove un solo link! Il comando "Remove All Links" rimuove effettivamente tutti i links instaurati con la tabella specificata. Nel caso dei relazionamenti della tabella CONTRACTS con le tabelle SALESMEN e CUSTOMERS considerati prima, verrebbero quindi eliminati entrambi i relazionamenti.
Esiste poi il comando JOIN che si instaura allo stesso modo con cui si procede con il comando LINK, con la sola differenza che occorre selezionare il comando "Join" anziché "Link" dal menu "Table" e che, selezionato questo comando, la tabella di sinistra viene automaticamente chiusa dal programma. Per rimuovere tutti i joins si seleziona invece il comando "Remove All Joins" anziché "Remove All Links". A differenza di un link, un join di ArcView crea una sorta di unione fisica temporanea tra le due tabelle che viene automaticamente rimossa quando si esce dal programma. Una volta instaurato un join, quindi, la tabella di sinistra appare all'utente veramente come se fosse stata espansa dei campi della tabella di destra, tant'è che questi campi aggiuntivi saranno disponibili, per esempio, anche nell'editor di legende delle visualizzazioni di ArcView.
Riprendendo l'esempio dei due relazionamenti tra le tabelle CONTRACTS e SALESMEN e tra le tabelle CONTRACTS e CUSTOMERS, con ArcView si procede nel modo seguente:
Dopodiché la tabella CONTRACTS apparirà all'utente nel modo seguente:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Dopo aver rimosso i joins, la tabella CONTRACTS apparirà di nuova all'utente senza i campi aggiuntivi SURNAME e CONTRACTS.
In sintesi, gli ambienti di relazionamento nei due software Arc/Info e ArcView hanno le seguenti caratteristiche:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Pagina creata il 22 maggio 1997
Per informazioni potete contattarmi all'indirizzo hedorfer@cidoc.iuav.unive.it