Algebra relazionale - operatori di base e join
In questa pagina 11
Prerequisiti: Modello relazionale - relazioni, chiavi e vincoliIl modello relazionale (Codd, IBM, 1970) rappresenta i dati con relazioni, cioè tabelle, ed è basato su valori: i legami tra relazioni sono confronti di valori, non puntatori, il che garantisce indipendenza dalle strutture fisiche, portabilità e bidirezionalità. Una relazione matematica è un sottoinsieme del prodotto cartesiano di n domini (insieme di n-uple ordinate, senza duplicati né ordine tra le righe); una relazione del modello è un insieme di tuple, funzioni dagli attributi ai valori del dominio, quindi non posizionale. Si distinguono schema di relazione e istanza, schema di base di dati (relazioni più vincoli) e istanza. NULL è un valore speciale fuori da ogni dominio. I vincoli di integrità sono intra-relazionali (di dominio, di tupla, di chiave) e inter-relazionali (integrità referenziale, con la chiave esterna). Superchiave: insieme di attributi che non ripete mai i valori; chiave: superchiave minimale; ogni relazione ne ha almeno una (tutti gli attributi); la chiave primaria è una chiave scelta, senza NULL.Modello relazionale - relazioni, chiavi e vincoli → (relazione come insieme di tuple, chiavi, chiavi esterne) e Operazioni tra insiemiUnione, intersezione, differenza, complementare e prodotto cartesiano, con le leggi di De Morgan e il legame con la logica.Operazioni tra insiemi → (unione, intersezione, differenza e prodotto cartesiano di insiemi). Si prosegue con Algebra relazionale estesa - divisione, aggregazione e outer joinL'algebra relazionale di base lavora una tupla alla volta e non sa fare calcoli sui valori né riassumere più tuple. L'estensione aggiunge: la proiezione generalizzata π_{F1,...,Fn}(R), che calcola espressioni sugli attributi (prezzo per quantità); l'aggregazione ℱ_{SUM, MAX, MIN, AVG, COUNT}(R), che produce una sola tupla; il raggruppamento (A1,...,Am)ℱ_{f(B)}(R), che produce una tupla per gruppo (grado n+m, cardinalità = numero di gruppi). Le funzioni di aggregazione ignorano i NULL, COUNT() conta le tuple, i NULL formano un gruppo a sé. Gli outer join (left, right, full) mantengono con NULL le tuple dangling del join; i NULL nella chiave di join non si accoppiano mai. La divisione R÷S dà gli x tali che (x,y) sta in R per ogni y di S, e si ottiene con π, × e −. Ricette: massimo = aggregazione + join con il massimo, "tutti" = divisione o complemento, "almeno due" = self-join.Algebra relazionale estesa - divisione, aggregazione e outer join → e con SQL - interrogazioni, join e aggregazioniUn'interrogazione SQL ha almeno SELECT e FROM; le altre clausole (WHERE, GROUP BY, HAVING, ORDER BY) sono opzionali e HAVING richiede GROUP BY. Ordine logico di valutazione: FROM, WHERE, GROUP BY, HAVING, SELECT, DISTINCT, ORDER BY. SELECT corrisponde a π (ma senza DISTINCT non elimina i duplicati), WHERE a σ, gli alias ad AS/ρ, i join a ⋈ (INNER, LEFT, RIGHT, FULL). WHERE seleziona le righe prima del raggruppamento, HAVING seleziona i gruppi dopo. Le funzioni COUNT, SUM, AVG, MIN, MAX ignorano i NULL (COUNT() conta le righe, DISTINCT toglie i duplicati dentro la funzione); con un aggregato o con GROUP BY nella SELECT possono comparire solo colonne di raggruppamento o aggregati. LIKE usa % (qualsiasi sequenza) e _ (un carattere). I confronti con NULL non sono veri: serve IS NULL. Un filtro sulla tabella di destra di un LEFT JOIN va nella clausola ON, non in WHERE, altrimenti il join diventa interno. Con interi COUNT(a)/COUNT(b) è una divisione intera: serve CAST.SQL - interrogazioni, join e aggregazioni →, che è la sua implementazione "reale". Gli esercizi svolti sono in Esercizio - Algebra relazionale su impiegati e dirigenti (esercizi di algebra relazionale del corso).
Operazioni sul modello relazionale
Dati uno schema e un'istanza del database, le operazioni si dividono in due famiglie:
- un aggiornamento è una funzione che porta l'istanza in una nuova istanza valida, cioè che rispetta tutti i vincoli di integrità;
- una interrogazione (query) è una funzione che porta l'istanza in una relazione (il risultato); il database non cambia.
Aggiornamenti e vincoli
| Operazione | Vincoli che può violare | Alternative |
|---|---|---|
| Inserimento | dominio, tupla, chiave, integrità referenziale | rifiutare l'inserimento; oppure correggere la causa della violazione |
| Modifica | dominio, tupla, chiave, integrità referenziale | rifiutare (restrict); oppure propagare (cascade) |
| Cancellazione | integrità referenziale | rifiutare (restrict); propagare (cascade); mettere a NULL (set null) o a un valore di default (set default) gli attributi che puntano |
Esempio.
Dipendente(matricola, cognome, reparto)conrepartochiave esterna versoReparto(codice, nome). Se si cancella il repartoDe tre dipendenti hannoreparto = 'D': con restrict la cancellazione è rifiutata; con cascade spariscono anche i tre dipendenti; con set null i tre restano conreparto = NULL; con set default passano al reparto di default (che deve esistere).
Set null è impossibile se l'attributo che punta fa parte della chiave primaria, perché una chiave primaria non può contenere NULL. In SQL queste scelte si dichiarano con ON DELETE e ON UPDATE, vedi SQL - definizione dei dati e vincoliSQL (standard ISO 9075) è un linguaggio dichiarativo con una parte di definizione dei dati (DDL: CREATE/DROP/ALTER di database, schemi, tipi enumerati, domini, tabelle) e una di manipolazione (DML: INSERT, DELETE, UPDATE, SELECT). Una tabella SQL è un multi-insieme di righe (può avere duplicati), quindi non è una relazione in senso stretto. CREATE TABLE elenca colonne con tipo e vincoli: NOT NULL, DEFAULT, CHECK (di colonna o di tupla), PRIMARY KEY (una sola, anche composta), UNIQUE, FOREIGN KEY ... REFERENCES con ON DELETE/ON UPDATE (NO ACTION, CASCADE, SET NULL, SET DEFAULT). I tipi principali sono CHAR/VARCHAR, NUMERIC, INTEGER, SERIAL, BOOLEAN, DATE, TIME, TIMESTAMP, più UUID, intervalli e JSON in PostgreSQL. DROP ... CASCADE cancella anche gli oggetti dipendenti, RESTRICT (predefinito) rifiuta se ce ne sono. DELETE e UPDATE senza WHERE agiscono su tutta la tabella.SQL - definizione dei dati e vincoli →.
L'algebra relazionale
L'algebra relazionale è un linguaggio procedurale: un'interrogazione dice come costruire il risultato, con una sequenza di operatori. Ogni operatore ha come operandi una o due relazioni e produce una relazione, quindi gli operatori si compongono in espressioni. (SQL invece è dichiarativo: dice che cosa si vuole.)
Poiché una relazione è un insieme, i duplicati non esistono: ogni risultato è privo di tuple ripetute. È la differenza principale rispetto a SQL, dove una tabella è un multi-insieme.
| Operatori | |
|---|---|
| Primitivi | unione , differenza , prodotto , rinomina , selezione , proiezione |
| Derivati | intersezione , join naturale , theta-join , outer join |
| Insiemistici | , , , |
| Relazionali | , , , join, outer join |
"Derivato" significa esprimibile con i primitivi, per esempio e .
Operatori insiemistici
Definizione (compatibilità all'unione). Due relazioni sono compatibili all'unione se hanno lo stesso numero di attributi e ogni coppia di attributi ha stesso nome e stesso dominio.
Intersezione, unione e differenza richiedono relazioni compatibili all'unione. Dati
| Graduated: Badge | Surname | Age |
|---|---|---|
| 7274 | Rossi | 42 |
| 7432 | Neri | 54 |
| 9824 | Verdi | 45 |
| Manager: Badge | Surname | Age |
|---|---|---|
| 9297 | Neri | 33 |
| 7432 | Neri | 54 |
| 9824 | Verdi | 45 |
i tre operatori danno (sempre senza duplicati):
- ;
- : le quattro tuple distinte , , , (le due tuple comuni compaiono una volta sola);
- : i laureati che non sono dirigenti. La differenza non è commutativa.
Definizione (prodotto). Date e , il prodotto ha schema , grado e cardinalità : ogni tupla del primo operando è concatenata a ogni tupla del secondo.
Il nome "prodotto cartesiano" è un po' improprio: il risultato non è l'insieme di coppie di tuple, ma di tuple "incollate". Con si hanno tuple di 6 attributi; poiché i due schemi hanno gli stessi nomi, per scrivere il prodotto bisogna prima rinominare (altrimenti ci sarebbero due attributi Badge).
Rinomina
Definizione (rinomina). cambia i nomi degli attributi in . Si modifica lo schema, non l'istanza: domini e valori restano.
Serve a due scopi: rendere compatibili all'unione due relazioni e distinguere gli attributi omonimi in un prodotto o in un join.
Esempio (compatibilità).
Paternity(Father, Child)eMaternity(Mother, Child)non sono compatibili (Father≠Mother). Per ottenere tutti i genitori: con schema e le sei tuple dei due operandi, per esempio e .
Esempio (più attributi). unisce
Clerk(Surname, Office, Salary)eWorker(Surname, Factory, Wages)nello schema .
Selezione
Definizione (selezione). ha lo stesso schema di e contiene il sottoinsieme delle tuple di che soddisfano la proposizione . La proposizione è:
- , con attributi di sullo stesso dominio;
- , con costante;
- dove ;
- combinazione di proposizioni con , , .
Dati Employee(Badge, Surname, Branch, Salary) con , , , :
- stipendio maggiore di 50: restituisce tre tuple (tutte tranne la terza);
- stipendio maggiore di 50 e filiale Milano: restituisce solo ;
- cognome uguale alla filiale (confronto tra due attributi): restituisce .
Proiezione
Definizione (proiezione). ha come schema un sottoinsieme degli attributi di e contiene le tuple di ristrette a quegli attributi. Il grado è ; la cardinalità è : è minore se, dopo aver tolto colonne, alcune tuple diventano uguali e (essendo un insieme) i duplicati spariscono; è uguale a se gli attributi proiettati contengono una superchiave.
Con lo stesso Employee, ha quattro tuple, mentre ne ha tre: compare una volta sola.
Selezione e proiezione insieme
Sono operatori ortogonali: la selezione fa una decomposizione orizzontale (sceglie righe), la proiezione una verticale (sceglie colonne).
"Badge e cognome dei dipendenti con stipendio maggiore di 50" si scrive : si valuta dall'interno all'esterno. Scambiare l'ordine, , è sbagliato: dopo la proiezione l'attributo Salary non esiste più e la selezione non è definita. In generale e non commutano; commutano solo quando gli attributi usati dalla selezione sono un sottoinsieme di quelli della proiezione.
Join
Il prodotto da solo produce quasi sempre tuple prive di senso (si accoppia ogni dipendente con ogni reparto). Il join accoppia solo le tuple "giuste".
Definizione (theta-join). Date e senza attributi omonimi e una proposizione che confronta attributi di con attributi di (e costanti), Grado ; cardinalità (detta anche selettività).
Se è una congiunzione di uguaglianze si parla di equi-join.
Esempio (equi-join). Con
Employee(Surname, Dep)= eDepartment(Code, Manager)= , dà , , : l'attributo di join compare due volte, con nomi diversi.
Definizione (join naturale). Siano e con e gli attributi con lo stesso nome. Allora
È un equi-join sugli attributi omonimi, seguito da una proiezione che tiene una sola copia di ogni attributo comune. Con Department(Dep, Manager) (stesso nome Dep in entrambe) dà , , .
Il join naturale è comodo ma fragile: se due relazioni hanno per caso un attributo omonimo che non va usato per il join (per esempio due Nome), il risultato cambia in silenzio. Nei temi d'esame conviene scrivere il join con la condizione esplicita (equi-join) e rinominare dove serve.
Cardinalità del join
Siano , e gli attributi su cui si fa il join naturale (o l'equi-join).
| Situazione | Cardinalità |
|---|---|
| caso generale | |
| è chiave di | |
| è chiave di e chiave esterna di verso , con vincolo di integrità referenziale |
Esempio.
Employee: (4 tuple).
Department= :Depnon è chiave, risultano 5 tuple (su un massimo di ): e si accoppiano con entrambi i dirigenti di , non si accoppia.Department= :Depè chiave ma non chiave esterna diEmployee(c'è senza reparto): 3 tuple, meno delle 4 diEmployee.- Con al posto di e lo stesso
Department:Depè chiave diDepartmente chiave esterna diEmployee: 4 tuple .
Tuple dangling
Una tupla che non trova corrispondente nell'altro operando non contribuisce al risultato: si dice dangling (pendente). Nell'esempio, di Employee e di Department scompaiono dal join. Per mantenerle, con valori NULL, servono gli outer join (Algebra relazionale estesa - divisione, aggregazione e outer joinL'algebra relazionale di base lavora una tupla alla volta e non sa fare calcoli sui valori né riassumere più tuple. L'estensione aggiunge: la proiezione generalizzata π_{F1,...,Fn}(R), che calcola espressioni sugli attributi (prezzo per quantità); l'aggregazione ℱ_{SUM, MAX, MIN, AVG, COUNT}(R), che produce una sola tupla; il raggruppamento (A1,...,Am)ℱ_{f(B)}(R), che produce una tupla per gruppo (grado n+m, cardinalità = numero di gruppi). Le funzioni di aggregazione ignorano i NULL, COUNT(*) conta le tuple, i NULL formano un gruppo a sé. Gli outer join (left, right, full) mantengono con NULL le tuple dangling del join; i NULL nella chiave di join non si accoppiano mai. La divisione R÷S dà gli x tali che (x,y) sta in R per ogni y di S, e si ottiene con π, × e −. Ricette: massimo = aggregazione + join con il massimo, "tutti" = divisione o complemento, "almeno due" = self-join.Algebra relazionale estesa - divisione, aggregazione e outer join →).
Join di una relazione con se stessa
Per accoppiare tuple della stessa relazione si usa la rinomina. Con Employee(Badge, Surname, Age, Salary) e Manage(Employee, Manager) (tutti gli attributi sono badge), "i dipendenti che guadagnano più del loro dirigente" richiede due copie di Employee: una per il dipendente, una rinominata per il dirigente.
Il passaggio con theta-join evita una selezione dopo un equi-join. Il risultato completo è nell'esercizio Esercizio - Algebra relazionale su impiegati e dirigenti (esercizi di algebra relazionale del corso).
Valori NULL
La selezione valuta ogni condizione atomica separatamente, e un confronto con NULL non è vero (il risultato è "sconosciuto"). Con Employee(Badge, Surname, Age, Branch): , , :
- restituisce solo Bianchi;
- restituisce solo Rossi;
- quindi : Neri sparisce da entrambe. Lo stesso vale per .
Per gestire i NULL si introducono le condizioni specifiche e :
Con la logica a tre valori (vero, falso, sconosciuto) , , si comportano così, e la selezione tiene solo le tuple per cui la condizione è vera:
| V | sconosciuto | sconosciuto | V | F |
| F | sconosciuto | F | sconosciuto | V |
| sconosciuto | sconosciuto | sconosciuto | sconosciuto | sconosciuto |
Anche nei join gli attributi NULL non si accoppiano mai: non è vero.
Come si scrive una query
- Individuare le relazioni coinvolte e gli attributi che servono nel risultato.
- Collegarle con join (sui legami chiave-chiave esterna), rinominando gli attributi omonimi o le copie della stessa relazione.
- Filtrare con (meglio il prima possibile, sulle relazioni piccole, prima dei join: il risultato è lo stesso ma l'espressione è più efficiente).
- Proiettare con solo gli attributi richiesti (e solo alla fine, se la selezione usa attributi che non si vedono nel risultato).
- Assegnare nomi alle relazioni intermedie () per leggibilità; le espressioni si leggono dall'interno all'esterno e da sinistra a destra.
- Controllare su due o tre tuple a mano, con attenzione ai duplicati, ai NULL e ai casi limite ("nessuno", "tutti", "almeno due").
Per i casi con "massimo", "tutti", "per ciascuno" servono l'aggregazione e la divisione, vedi Algebra relazionale estesa - divisione, aggregazione e outer joinL'algebra relazionale di base lavora una tupla alla volta e non sa fare calcoli sui valori né riassumere più tuple. L'estensione aggiunge: la proiezione generalizzata π_{F1,...,Fn}(R), che calcola espressioni sugli attributi (prezzo per quantità); l'aggregazione ℱ_{SUM, MAX, MIN, AVG, COUNT}(R), che produce una sola tupla; il raggruppamento (A1,...,Am)ℱ_{f(B)}(R), che produce una tupla per gruppo (grado n+m, cardinalità = numero di gruppi). Le funzioni di aggregazione ignorano i NULL, COUNT(*) conta le tuple, i NULL formano un gruppo a sé. Gli outer join (left, right, full) mantengono con NULL le tuple dangling del join; i NULL nella chiave di join non si accoppiano mai. La divisione R÷S dà gli x tali che (x,y) sta in R per ogni y di S, e si ottiene con π, × e −. Ricette: massimo = aggregazione + join con il massimo, "tutti" = divisione o complemento, "almeno due" = self-join.Algebra relazionale estesa - divisione, aggregazione e outer join →. Con i soli operatori di questa nota si possono già esprimere i "per tutti" con la differenza: "i dirigenti i cui dipendenti guadagnano tutti più di 42" , cioè tutti i dirigenti meno quelli che hanno almeno un dipendente sotto soglia. È il metodo del complemento: "tutti" = "non esiste nessuno che non".
Errori tipici
- Scrivere per "dirigenti che hanno a loro volta un dirigente": confronta due attributi della stessa tupla, quindi trova chi dirige se stesso (nessuno). Serve un join della relazione con una sua copia rinominata.
- Fare la proiezione prima della selezione quando la selezione usa attributi eliminati.
- Usare un join naturale tra relazioni con attributi omonimi che non c'entrano.
- Dimenticare la rinomina nelle unioni (relazioni non compatibili) e nei join con se stessi.
- Ignorare i NULL: .
- Dare per scontato che il risultato contenga duplicati: in algebra non ce ne sono.
Domande d'esame
1. Quando due relazioni sono compatibili all'unione e perché la rinomina serve prima di un'unione?
Traccia. Stesso numero di attributi con stessi nomi e domini. Se i nomi sono diversi (Father/Mother) l'unione non è definita: si rinominano gli attributi con cambiando solo lo schema, poi si fa .
2. Perché non si può riscrivere come ?
Traccia. La proiezione elimina Salary, quindi la selezione che segue usa un attributo inesistente. Selezione e proiezione commutano solo se gli attributi della selezione sono tra quelli proiettati.
3. Quante tuple ha se l'attributo di join è chiave di e chiave esterna di ? Traccia. Esattamente : ogni tupla di ha una sola tupla corrispondente in (esiste per l'integrità referenziale ed è unica perché è una chiave).
4. Cosa restituisce se ha valori NULL? Traccia. Non tutta : un confronto con NULL non è vero, quindi le tuple con nullo mancano in entrambe. Servono / .
Versione ripasso
Operazioni: un aggiornamento porta l'istanza in una nuova istanza valida; un'interrogazione porta l'istanza in una relazione. Cancellazione con integrità referenziale: restrict, cascade, set null (non su chiave primaria), set default. In SQL: ON DELETE e ON UPDATE (SQL - definizione dei dati e vincoliSQL (standard ISO 9075) è un linguaggio dichiarativo con una parte di definizione dei dati (DDL: CREATE/DROP/ALTER di database, schemi, tipi enumerati, domini, tabelle) e una di manipolazione (DML: INSERT, DELETE, UPDATE, SELECT). Una tabella SQL è un multi-insieme di righe (può avere duplicati), quindi non è una relazione in senso stretto. CREATE TABLE elenca colonne con tipo e vincoli: NOT NULL, DEFAULT, CHECK (di colonna o di tupla), PRIMARY KEY (una sola, anche composta), UNIQUE, FOREIGN KEY ... REFERENCES con ON DELETE/ON UPDATE (NO ACTION, CASCADE, SET NULL, SET DEFAULT). I tipi principali sono CHAR/VARCHAR, NUMERIC, INTEGER, SERIAL, BOOLEAN, DATE, TIME, TIMESTAMP, più UUID, intervalli e JSON in PostgreSQL. DROP ... CASCADE cancella anche gli oggetti dipendenti, RESTRICT (predefinito) rifiuta se ce ne sono. DELETE e UPDATE senza WHERE agiscono su tutta la tabella.SQL - definizione dei dati e vincoli →).
Algebra: linguaggio procedurale, gli operatori si compongono. Una relazione è un insieme: niente duplicati. Primitivi: , , , , , . Derivati: , , , outer join. Esempi: e .
Compatibilità all'unione: stesso numero di attributi, stessi nomi e stessi domini; serve per , , . Con Graduated e Manager (tre tuple ciascuna): dà (7432,Neri,54) e (9824,Verdi,45); dà quattro tuple distinte; dà solo (7274,Rossi,42). La differenza non è commutativa.
Prodotto: grado , cardinalità ; con attributi omonimi serve prima la rinomina. Con 3 tuple per 3 tuple si ottengono tuple.
Rinomina : cambia lo schema, non l'istanza. Esempio: .
Selezione : stesso schema, sottoinsieme delle tuple che soddisfano . Confronti o , combinati con , , . Con Employee: dà tre tuple; dà solo (5998,Neri,Milano,64); dà (9553,Milano,Milano,44).
Proiezione : al più tuple, i duplicati spariscono. È uguale a se contiene una superchiave. Con Employee, dà tre tuple perché (Rossi,Roma) compare una volta sola.
Selezione e proiezione: la selezione è una decomposizione orizzontale (righe), la proiezione una verticale (colonne). si valuta dall'interno; scambiare le due è sbagliato, perché Salary sparisce con la proiezione. Commutano solo se gli attributi della selezione sono nella proiezione.
Theta-join ed equi-join: , con . Se è una congiunzione di uguaglianze è un equi-join. Esempio: Employee(Surname, Dep) con Department(Code, Manager) su dà tre tuple, con l'attributo di join due volte.
Join naturale: equi-join sugli attributi omonimi, poi proiezione che tiene una copia sola. È fragile: due omonimi che non c'entrano cambiano il risultato in silenzio. Negli esami conviene l'equi-join esplicito.
Cardinalità del join:
- caso generale: ;
- chiave di : ;
- chiave di e chiave esterna di , con integrità referenziale: .
Con Employee di quattro tuple, il join con Department dà 5, 3 o 4 tuple a seconda che Dep sia o no chiave e chiave esterna.
Self-join: si rinomina una copia della relazione. Per "dipendenti che guadagnano più del loro dirigente":
Valori NULL: un confronto con NULL non è vero. Se Neri ha Age = NULL, . Soluzione: aggiungere alla condizione. Logica a tre valori: , ; la selezione tiene solo le tuple vere. Nei join i NULL non si accoppiano.
Il "tutti": i dirigenti i cui dipendenti guadagnano tutti più di 42 sono tutti i dirigenti meno quelli con almeno un dipendente sotto soglia:
Errori tipici:
- per "chi ha a sua volta un dirigente": confronta due attributi della stessa tupla, serve un self-join;
- proiettare prima di selezionare su un attributo eliminato;
- join naturale su omonimi che non c'entrano, o rinomina dimenticata nelle unioni;
- ignorare i NULL, aspettarsi duplicati.
Prerequisiti: Modello relazionale - relazioni, chiavi e vincoliIl modello relazionale (Codd, IBM, 1970) rappresenta i dati con relazioni, cioè tabelle, ed è basato su valori: i legami tra relazioni sono confronti di valori, non puntatori, il che garantisce indipendenza dalle strutture fisiche, portabilità e bidirezionalità. Una relazione matematica è un sottoinsieme del prodotto cartesiano di n domini (insieme di n-uple ordinate, senza duplicati né ordine tra le righe); una relazione del modello è un insieme di tuple, funzioni dagli attributi ai valori del dominio, quindi non posizionale. Si distinguono schema di relazione e istanza, schema di base di dati (relazioni più vincoli) e istanza. NULL è un valore speciale fuori da ogni dominio. I vincoli di integrità sono intra-relazionali (di dominio, di tupla, di chiave) e inter-relazionali (integrità referenziale, con la chiave esterna). Superchiave: insieme di attributi che non ripete mai i valori; chiave: superchiave minimale; ogni relazione ne ha almeno una (tutti gli attributi); la chiave primaria è una chiave scelta, senza NULL.Modello relazionale - relazioni, chiavi e vincoli →, Operazioni tra insiemiUnione, intersezione, differenza, complementare e prodotto cartesiano, con le leggi di De Morgan e il legame con la logica.Operazioni tra insiemi →. Esercizi: Esercizio - Algebra relazionale su impiegati e dirigenti (esercizi di algebra relazionale del corso).