Guida [GUIDA] Basi di dati - L'algebra relazionale

Stato
Discussione chiusa ad ulteriori risposte.

syscall

Utente Emerald
21 Settembre 2013
683
43
581
475
Ultima modifica da un moderatore:
Salve a tutto il popolo di inforge e ai fruitori del sapere e della conoscenza in generale, felici di rileggermi? :nono: .. ok .-.

Continuiamo, dopo un piccolo stop, a parlare di basi di dati.. oggi la storia e' un po piu' rottura e prevede particolare attenzione, quindi state ben attenti mi raccomando.

Finalmente la tanto attesa guida (ma anche no LOL), affronteremo un argomento molto importante, parleremo di algebra relazionale.

Durante le guide precedenti, che vi invito a leggere/rileggere abbiamo definito due tipologie di linguaggi che operano sulla base di dati, quali:

- Linguaggi che operano sullo schema == DDL
- Linguaggi che operano sulle istanze == DML

A loro volta, i DML, si distinguono in linguaggi di Interrogazione e Aggiornamento.

Nello specifico, l'algebra relazionale e' un linguaggio di interrogazione, che e' procedurale in quanto specifica le modalita' operative per ottenere il risultato.

Nella pratica l'algebra relazionale e' costituita da una serie di operatori su relazioni che come risultato forniscono ancora una relazione. Molti degli operatori sono noti, in quanto sono operatori insiemistici, in particolare vedremo:

- Unione
- Intersezione
- Differenza

Inoltre, altri operatori sono estremamente specifici ed utilizzati in un contesto di basi di dati, e sono:

- Ridenominazione
- Selezione
- Proiezione
- Join (naturale/prodototto cartesiano/theta-join)

Mo vediamo un attimo gli operatori insiemistici che possono essere applicati a relazioni definite sugli stessi attributi.

Iniziamo con l'operatore di unione, osservando le relazioni dell'immaginetta sotto.

2i24ggz.png

Entrambe le relazioni si riferiscono a dei libri, in particolare magari i libri piu' venduti in un determinato periodo di tempo (i successi di un dato periodo) ed i "classici", entrambe le relazioni sono definiti sugli stessi attributi ed in particolare hanno l'attributo titolo, genere ed autore. Osservando le varie tuple, in effetti l'unica riga che si ripete nelle due relazioni e' "l'idiota".

Se andiamo a fare l'unione (U) - Successi U Classici -, il risultato di questa operazione sara' quello visualizzato nella tabellina a destra dell'immagine.

Il numero totale delle n-uple della relazione ottenuta come unione tra le due relazioni e' costituita da sei righe, in realta', nel momento in cui abbiamo unito le due relazioni abbiamo dovuto eliminare le righe ripetute per definizione di relazione, ricordate no?, e comunque in un insieme non possono esserci righe uguali, pertanto, "l'idiota" ha una sola occorrenza!

Il secondo operatore e' l'operatore di Intersezione..

29aruab.png

..e restituisce una relazione delle righe comuni: - Successi \cap Classici -, da come risultato un'unica riga, infatti "l'idiota" e' presente sia nella relazione successi che sia nella relazione classici

Procedendo, possiamo vedere l'operatore differenza.

3005jdh.png

- Successi-Classici -, restituisce una relazione in cui sono presenti tutte le righe contenute nella prima relazione (successi) e che non sono contenuti nella seconda, ancora una volta abbiamo quindi "l'idiota" che e' presente nella relazione classici e viene escluso.

Bene, unione, intersezione e differenza erano quelli "soft", piu' noti, che tutti sicuramente conosciamo.
Da adesso parleremo di operatori specifici, usati solo in contesti di basi di dati, namo va!

Operatore di Ridenominazione:

Ci permette di modificare il nome dell'attributo, attenzione che quando si parla di "modifiche alla base dati", in realta' non e' una corretta e perfetta dizione, in quanto il risultato e' comunque un'estrazione di una serie di n-uple e quindi si ottiene effettivamente un risultato e si opera sul risultato, in sostanza la base di dati rimane invariata, quindi quando si parla di cambio del nome dell'attributo, stiamo parlando di un cambio all'interno del risultato, quindi se noi analizziamo successi e classici, sono le stesse relazioni degli esempi precedenti solo che in questo caso, nella relazione classici, abbiamo come attributi titolo tipo e autore, si capisce ovviamente che tipo e' semplicemente un nome alternativo a genere, solo che ci serve per chiarire il concetto appunto di ridenominazione.

Qualora volessimo procedere con l'unione tra successi e classici dovremmo ridenominare l'attributo tipo cambiando il nome in genere, in modo tale che le entrambe relazioni siano definiti sugli stessi attributi (poiche' ricordiamo che per poter utilizzare gli operatori insiemistici e' necessario che le relazioni su cui sia agisce siano definititi sugli stessi attributi).

1zqdish.png

Si esprime scrivendo REN, poi si indica che l'attributo tipo e' ridenominato in genere e questo avviene sulla relazione classici (vedere immaginetta). Si tenga presente che potremmo anche ridenominare contemporaneamente piu' attributi, in questo caso si dovrebbe utilizzare una virgola separando i vari nomi originari e allo stesso stesso modo i nomi degli attributi nuovi, in questo caso le posizioni ci indicano il nuovo nome da attribuire all'attributo di cui si sta modificando il nome (che si sta ridenominando ovviamente). Il risultato della ridenominazione sulla relazione classici e dell'attributo tipo sul nome genere e' RENgenere <- tipo (Classici). Si ottiene quindi lo stesso risultato che avevamo in precedenza!

Adesso, potremmo applicare, dopo aver effettuato la ridenominazione, sia l'intersezione che la differenza che l'unione.

Procedendo con gli operatori, adesso ne vediamo uno particolarmente importante, quello di Selezione.

Quest'operatore ci permette di ottenere come risultato un sottoinsieme delle n-uple dell'operando, questo, come quello di ridenominazione, opera soltanto su una relazione (solo un operando) e ci permette in qualche modo, con una definizione "light", di filtrare il contenuto di una tabella.. Vediamo nell'immaginetta sotto l'esempio:

jj08bp.png


Sulla tabella libri vorremmo poter selezionare solo una parte di essa (solo alcune delle righe), magari tutti quelli scritti da un determinato autore, o tutti i romanzi o tutti i saggi, facciamo due esempi concreti, proviamo ad estrarre, a selezionare tutti i saggi contenuti nella relazione libri e poi tutti i romanzi scritti da Calvino.

Anticipiamo che l'operatore di selezione si scrive come: SELcondizione(Operando) (diciamo che la condizione e' pedice di selezione, qua non ho assolutamente idea di come scrivere in modo "matematicoso" quindi bo, vi faccio capire comunque nell'immaginetta quel che intendo!), per cui, volendo estrarre tutti i saggi potremmo fare una roba simile: SELgenere='saggio'(Libri). SEL (selezioniamo tutte le righe), in cui "genere" e' uguale a "saggio", abbiamo inserito le virgolette in "saggio" poiche' si tratta di una stringa, quest'ultime tipicamente vengono inserite in apici o doppi apici e questa operazione avviene ovviamente sulla relazione libri, e quindi, ripetiamolo per l'ennesima volta per chiarezza, stiamo estraendo tutte le righe in cui l'attributo genere e' uguale a saggio e il risultato sara' un sotto insieme di n-uple estratto dalla tabella originale libri, nel nostro caso soltanto due righe soddisfano la condizione indicata ed e' in particolare "un ultimo giro di giostra" e "Un indovino mi disse" entrambi di Terzani, nelle altre righe abbiamo romanzi, tranne una novella di Calvino che comunque non soddisfano la condizione indicata!

Vediamo un'altra selezione: SELautore='Calvino' AND genere='romanzo'(Libri)

243gfls.png

Tutti i romanzi scritti da Calvino, in questo caso la selezione ha come condizione un'espressione booleana che utilizza l'operatore AND, in particolare dobbiamo ricavare dall'attributo autore (il fatto che sia stato scritto da Calvino), pero' non vogliamo soltanto i libri di calvino ma i romanzi, cioe' vogliamo estrarre le righe in cui l'autore e' calvino e contemporaneamente che il genere sia "romanzo", per cui la riga di "Marcovaldo" viene esclusa, come ovviamente tutte le altre!

Ma andiamo avanti, il successivo operatore e' quello di Proiezione, che insieme a selezione e' uno dei piu' importanti che agisce sulle colonne (mentre selezione sulle righe ovviamente), ovvero sugli attributi, e quindi si dice che e' un operatore "ortogonale alla selezione". Il risultato che produce e' costituito da un sottoinsieieme degli attributi dell'operando ed un numero di n-uple minore o uguale a quelle dell'operando stesso, sotto l'immaginetta con esempio + sintassi:

2da0l89.png


PROJelencoattributi(Operando)

Se vogliamo la proiezione di Codice e titolo e di Autore e Genere, allora la esprimeremo cosi':

33lmozl.png

PROJcodice, titolo(Libri)

In questo caso il codice che e' stato aggiunto precedentemente nella tabella libri, ci assicura che non esistano righe uguali, naturalmente nel caso in cui dovesse verificarsi una ripetizione di righe, la condizione non sarebbe ammissibile e quindi andrebbe esclusa dal risultato.

Il risultato ci fornisce lo stesso numero di righe dell'operando stesso, le righe sono undici sia nel caso della relazione originale sia appunto nel caso del risultato dell'operazione di relazione.

Il successivo esempio nell'immaginetta invece:

2a6w6yr.png

..mostriamo la proiezione di autore e genere!

In questo caso si verifica il "problema" di prima, ovvero alcune righe si ripetono, queste righe invalidano la relazione, per cui da questo risultato vanno eliminate le righe uguali e il risultato finale sara' il seguente:
1124gtj.png


Risultato finale dell'operatore di proiezione applicato alla relazione libri, chiaro no!? Spero di si, non so in che altro modo spiegarlo :D

Bon, risultati interessanti si ottengono combinando i due operatori, ovvero selezione e proiezione, vediamone un esempio:
kaie5y.png


Immaginiamo di avere sempre la nostra relazione libri, immaginiamo di voler solo titoli degli autori dei libri che sono romanzi! Quindi le righe che soddisfano la condizione genere="romanzi".

PROJtitolo,autore(SELgenere="romanzo"(Libri))

In questo caso l'operatore di selezione escludera' dal risultato la riga 8, 9, 10, il risultato finale dell'operazione di selezione sara' pari a tutte le righe tranne le tre righe in cui il genere non e' romanzo!

Questi operatori pero' lavorano solo so una relazione, nella realta' c'e' la necessita' di correlare dati e quindi di lavorare su piu' tabelle contemporaneamente e per fare cio' si usa l'operatore Join!

Vediamo un attimo il Join (naturale), che consente di correlare dati posti in relazioni diverse ed il risultato di un'operazione di join e' una unione degli attributi degli operandi e le n-uple sono generate partendo da una n-upla di ciascun operando.
30ndi6d.png

Le relazioni anno in comune l'attributo CadAutore, grazie alla presenza di questo attributo possiamo ottenere il risultato del join naturale, esiste quindi una correlazione fra le righe di libri/autori.

I risultato del join sara' il seguente:
2945fn9.png

Avremo l'insieme delle n-uple della tabella libri ed in particolare gli attributi della tabella libri uniti con gli attributi della tabella autori, non appare il codice autore che e' l'attributo attraverso cui e' stato effettivamente effettuato il join (sono state associate le righe della tabella autori quando coincideva l'attributo codAutore).

Possiamo un attimo dare una definizione "standard" per formalizzare il join naturale dicendo

E1(X1) R2(X2) -> R1 JOIN R2 e' una relazione R su X1 X2 costituita dalle n-uple t su X1 X2 tali che esistano t1 in R1 e t2 in R2 per le quali t[X1]t e t[X2]=t2

Quindi, per chi non fosse "amante" di questo tipo di scrittura possiamo dirla in altre parole, stile inforge :D, ok: date le relazioni R1 definita su un insieme di attributi X con 1 ed R2 definita su un insieme di attributi X2, con 2 R1 JOIN R2 e' una nuova relazione R sull'unione degli attributi X con 1 e X con 2 costituita dalle n-uple t su X con 1 e X2 tali che esistano t1 in R1 e t2 in R2 per le quali t su X1 e' uguale a t1 e t su X2 e' uguale a t2!

Di join esistono piu' varianti, vedremo infatti:

- Join esterno
- Prodotto cartesiano
- Equi-join
- Theta--join

Per capire il discorso sul join esterno guardiamo le immaginette qua sotto:
2usamn8.png

Nel caso delle due relazioni dipartimento e' l'attributo comune, effettuando il join naturale si ottiene Rossi-Fisica-Bianchi (infatti fisica trova riferimento nella tabella responsabili) e Neri-Meccanica-Bruni (idem), ma rimangono escluse alcune righe (veri) perche' matematica non ha alcuna corrispondenza nella relazione responsabile, allo stesso modo Chimica-Gialli non trovando alcuna corrispondenza nella tabella docenti viene escluso dal risultato!

Anche se comunque in alcuni casi e' utile riportare le righe originali anche se non si trovano corrispondenze nel campo comune, e in questo caso si ricorre al join esterno, che a sua volta e' di piu' tipi:

- Left
- Right
- Full
2dln2h5.png

Riconsideriamo quindi l'esempio precedente, l'attributo dipartimento e' l'attributo su cui avviene il join naturale, (primo risultato a destra), in cui vengono escluse le righe che non trovano corrispondenza nell'altra relazione.

Successivamente abbiamo il join sinistro che riporta le righe che si otterrebbero comunque da un join naturale includendo le righe della tabella docenti per le quali comunque non si trova corrispondenza (dove cioe' matematica nell'esempio concreto sarebbe Verdi) inserendo nell'attributo che non ha corrispondenza nella tabella responsabili il valore NULL.

Simmetricamente si puo' ragionare sul join right, in questo caso abbiamo tutte le righe che comunque si otterrebbero con il join naturali + le righe della tabella responsabili per le quali non abbiamo un valore corrispondente nella tabella docenti! In tal caso nella riga aggiunta viene posto il valore NULL al campo docente.

Il full join invece fa un unione del join sinistro e destro (tutte le righe di docenti e responsabili) e vengono assegnati valori NULL per le quali non esistono corrispondenze nelle rispettive tabelle.

Il join successivo che prendiamo in considerazione, cari inforgiani, e' il prodotto cartesiano!
Valutiamo la relazione libri ed autori, in questo caso le due relazioni non hanno attributi comuni.
dyt7rc.png


In realta' RifAut e CodAutore diciamo che a livello "logico/intuitivo" forniscono la stessa informazione ma, dal punto di vista formale, i due attributi sono differenti, per cui, il prodotto cartesiano, e' esattamente la combinazione di ciascuna riga della prima tabella con tutte le righe della seconda tabella.
Naturalmente di tutte le righe molte forniscono informazioni inesatte/inutile, e' evidente che le uniche righe utili, che forniscono informazioni valide, sono quelle per le quali il riferimento autore == al codice autore! (ma per far capire la cosa bisogna farlo in questo modo :D)

Per cui si abbia comunque un risultato valido e' necessario estrarre solo le tabelle per le quale il riferimento rifaut sia uguale a cod autore, e questo ormai abbiamo imparato a farlo usando l'operatore select, quindi:
2d2ac1k.png

Le operazioni sono riportate nell'immaginetta, analizziamola un attimo:

Effettuiamo il prodotto cartesiano di Libri JOIN Autori e il risultato del prodotto cartesiano viene selezionato e come condizione abbiamo RifAut=CodAutore.
L'intero risultato e' ancora un join, e questo risultato prende il nome di theta join! Se nella condizione del theta join appare un operatore di uguaglianza si parla di equi-join. Quest'espressione viene convenzionalmente tradotta come Libri JOIN(rifaut=CodAutore)Autori.

Il risultato dell'espressione sara' la relazione in tabella sulla figura sopra, dove si nota subito che vengono escluse le righe per cui rifaut e' diverso da codautore!
Successivamente potremmo considerare che di fatto rifaut e codautore riportano informazioni "inutili", c'e' una forma di ridondanza eccessiva, ne basterebbe uno solo in quanto le colonne riportano valori coincidenti ma anche uno sarebbe di troppo in quanto l'informazione di autore l'abbiamo gia' e non dobbiamo ricavarla (aveva un senso solo quando le due relazioni erano separate). In questo caso, che abbiamo effettuato il JOIN, possiamo tranquillamente ed ulteriormente al risultato ottenuto, combinare una proiezione, quindi applicare PROJ scrivendo l'espressione che applica al theta join la proiezione su titolo,autore:

PROJtitolo,autore (Libri JOINrifaut=codautoreAutori) -> vedete immaginetta sopra per capire cosa e' pedice e cosa no mi raccomando!

Bene, il risultato di questa espressione sara' titolo,autore:
14wbwk4.png


Ohhhhhhh, con il theta join abbiamo completato la visione di tutti gli operatori che costituiscono il linguaggio dell'algebra relazionale, con essi possiamo interrogare le basi di dati e ottenere quindi proiezioni, selezioni e possiamo lavorare estraendo e interrogando i dati a nostro piacimento, e quindi siamo un po' piu' achari di prima :D

PS: siccome sono un particolarmente esaurito oggi e visto che c'ho messo 5 ore a fare sta roba non me la sento proprio di rileggermela tutta, come al solito, fra non molto do na ripassata a correggere gli eventuali errori di battitura o simili presenti all'interno del testo, intanto prendetela come una sorta di "bozza" piu' o meno seria dell'argomento .. La prossima volta comunque parleremo di.. dai arrivateci, non ve lo dico, lo scoprirete da soli!

STAY TUNED!
 
Stato
Discussione chiusa ad ulteriori risposte.