Andrea De Lorenzo, University of Trieste
Programmazione avanzata
Introduction to machine learning
evolutionary computation, embodied AI, applied ML
Cyber-physical systems
Information retrieval and data visualization
Laboratorio di programmazione
formal methods, runtime verification
Fondamenti di informatica
Laboratorio di cybersecurity
explainable AI; federated learning; data streaming
Architetture dei calcolatori
Sistemi operativi
Aadvanced computer networks
network measurements, data privacy, big data
Giorno | Orario | Aula |
---|---|---|
Martedì | 11:00 - 13:30 | Aula B Idraulica - C2 |
Mercoledì | 11:00 - 13:30 | Aula B Idraulica - C2 |
Venerdì | 9:00 - 10:30 | Aula B Idraulica - C2 |
L’essere umano genera e gestisce tante informazioni:
... salvate in tanti modi diversi
Anche le organizzazioni generano informazioni:
Le informazioni vanno codificate
Informazione: notizia, dato o elemento che consente di avere conoscenza più o meno esatta di fatti, situazioni, modi di essere
Dato: elemento di informazione costituito da simboli che debbono essere elaborati
Lun - Ven
Sabato
Festivi
Come codifico i numeri?
10010011110011001111
Che numero è?
Codifica | Dato | Informazione |
---|---|---|
Binario | 10010011110011001111 | 605391 |
Compleamento a due | 10010011110011001111 | -443185 |
Vigola mobile* | 10010011110011001111 | 8.48333e-40 |
* con qualche zero davanti
separare i dati dalle applicazioni che operano su essi
Collezione di dati, utilizzati per rappresentare le informazioni di interesse per una o più applicazioni di una organizzazione.
Software in grado di gestire collezioni di dati che siano:
Collezione di dati, utilizzati per rappresentare le informazioni di interesse per una o più applicazioni di una organizzazione
Collezione di dati gestita da un DBMS
Un DBMS deve garantire:
FS | DBMS | |
---|---|---|
Grandi moli di dati | ✓ | ✓ |
Persistenti | ✓ | ✓ |
Condivisi | ✓ | ✓ |
Affidabile | ✓ | ✓ |
Privatezza | ✓ | ✓ |
Efficienza | ? | ? |
Efficacia | X | ✓ |
Descrizione dei dati contenuta nell'applicazione
Aggiorno il programma di gestione ordini
Descrizione dei dati contenuta nell'applicazione
Analisi del problema
Modello astratto
Non dipende dallo strumento utilizzato
Come rappresentare i dati individuati con il modello concettuale
Nei vecchi sistemi il modo in cui venivano organizzati i dati e le tecniche per accedervi facevano parte della logica e del codice del programma.
In ogni base di dati esistono:
Permettono di rappresentare i dati in modo indipendente da ogni sistema:
Modello più diffuso: Entity-Relationship
Rappresentazione dello schema logico per mezzo di strutture di memorizzazione
Come è organizzato il DB. Diverse soluzioni:
Lo schema logico è INDIPENDENTE da quello fisico
Es: una tabella è utilizzata sempre allo stesso modo qualunque sia la sua realizzazione fisica (che può variare nel tempo)
L'amministratore del DB può modificare la struttura interna dei dati senza toccarne la visibilità esterna
IMMUNITÀ DELLE APPLICAZIONI A MODIFICHE DI STRUTTURA
Corso | Docente | Aula |
---|---|---|
Reti | Bartoli | N3 |
Programmazione | Medvet | N3 |
ML | Medvet | G |
Nome | Edificio | Piano |
---|---|---|
DS1 | H3 | 3 |
N3 | C2 | 2 |
G | Principale | PT |
Corso | Docente | Aula | Edificio | Piano |
---|---|---|---|---|
Reti | Bartoli | N3 | C2 | 2 |
Programmazione | Medvet | N3 | C2 | 2 |
ML | Medvet | G | Principale | PT |
Nome | Cognome | Matricola | Media | ISEE |
---|---|---|---|---|
Tizio | Caio | IN0001 | 30 | 5000€ |
Bubba | Gump | IN0003 | 27 | 1000000€ |
Jean Luc | Picard | IN0004 | 19 | 40000€ |
Nome | Cognome | Matricola | ISEE |
---|---|---|---|
Tizio | Caio | IN0001 | 5000€ |
Bubba | Gump | IN0003 | 1000000€ |
Jean Luc | Picard | IN0004 | 40000€ |
Nome | Cognome | Matricola | Media |
---|---|---|---|
Tizio | Caio | IN0001 | 30 |
Bubba | Gump | IN0003 | 27 |
Jean Luc | Picard | IN0004 | 19 |
Problemi:
Liberarsi dei puntatori fisici
Tabelle: organizzazione rettangolare di dati
Esami | |||
---|---|---|---|
Studente | Voto | Corso | |
276545 | 32 | 01 | |
276545 | 30 | 02 | |
787643 | 27 | 03 | |
787643 | 24 | 04 |
Studenti | ||
---|---|---|
Matricola | Cognome | Nome |
276545 | Rossi | Mario |
787643 | Neri | Piero |
787642 | Bianchi | Luca |
Corsi | ||
---|---|---|
Codice | Titolo | Docente |
01 | Analisi | Mario |
02 | Chimica | Bruni |
04 | Chimica | Verdi |
Tutte le informazioni in un DBR sono rappresentate esplicitamente da valori in tabelle (DEFINIZIONE)
Ciascun valore deve essere raggiunto univocamente da un nome di tabella, chiave primaria e nome di colonna (CHIAVI PRIMARIE)
Sono supportati per rappresentare informazioni mancanti indipendentemente dal tipo di dato
Un data base relazionale deve essere strutturato logicamente come i dati e gestibile con lo stesso linguaggio
Un DBR può supportare diversi linguaggi, ma deve supportare un linguaggio “English like” dove sia possibile (DEFINIZIONE DI SQL):
Le viste che sono modificabili teoricamente dall’utente lo devono essere anche dal sistema (cruciale per campi calcolati);
Affinché una vista sia modificabile, il DBMS deve essere in grado di tracciare ciascuna colonna e ciascuna riga UNIVOCAMENTE fino alle tabelle origine
Corso | Docente | Aula |
---|---|---|
Reti | Bartoli | N3 |
Programmazione | Medvet | N3 |
ML | Medvet | G |
Nome | Edificio | Piano |
---|---|---|
DS1 | H3 | 3 |
N3 | C2 | 2 |
G | Principale | PT |
Corso | Docente | Aula | Edificio | Piano |
---|---|---|---|---|
Reti | Bartoli | N3 | C2 | 2 |
Programmazione | Medvet | N3 | C2 | 2 |
ML | Medvet | G | Principale | PT |
Studente | Esame | Voto |
---|---|---|
Scaini | Reti | 30 |
Scaini | ML | 28 |
Bassi | ML | 30 |
Bassi | Reti | 30 |
Studente | Media |
---|---|
Scaini | 29 |
Bassi | 30 |
Inserire e aggiornare devono avere la stessa logica “a righe” dell’estrazione (SET ORIENTED)
I programmi applicativi non devono sentire alcuna modifica fatta sul metodo e la locazione fisica dei dati
Le modifiche al livello logico non devono richiedere cambiamenti non giustificati alle applicazioni che utilizzano il database (VISTE)
Vincoli di integrità devono essere implementabili sul motore (cruciale)
La distribuzione di porzioni del database su una o più allocazione fisiche o geografiche deve essere invisibile agli utenti del sistema
Garantisce l’impossibilità di bypassare le regole di integrità
Data Base dove tutti i dati visibili all’utente sono organizzati strettamente in tabelle di valori, e dove tutte le operazioni vengono eseguite su tabelle e danno come risultato tabelle.
Associazione nel modello Entity-Relationship
a | x |
a | y |
a | z |
b | x |
b | y |
b | z |
a | x |
a | z |
b | y |
Juve | Lazio | 3 | 1 |
Lazio | Milan | 2 | 0 |
Juve | Roma | 2 | 0 |
Roma | Milan | 0 | 1 |
A ciascun dominio si associa un nome (attributo), che ne descrive il "ruolo"
Casa | Fuori | RetiCasa | RetiFuori |
---|---|---|---|
Juve | Lazio | 3 | 1 |
Lazio | Milan | 2 | 0 |
Juve | Roma | 2 | 0 |
Roma | Milan | 0 | 1 |
I riferimento fra dati in relazioni diverse sono rappresentati per mezzo di valori dei domini che compaiono nelle $n$-uple
Studenti | |||
---|---|---|---|
Matricola | Cognome | Nome | DataDiNascita |
6554 | Rossi | Mario | 05/12/1978 |
8765 | Neri | Paolo | 03/11/1976 |
9283 | Verdi | Luisa | 12/11/1978 |
3456 | Rossi | Maria | 01/02/1978 |
Esami | ||
---|---|---|
Studente | Voto | Corso |
3456 | 30 | 04 |
3456 | 24 | 02 |
9283 | 28 | 01 |
6554 | 26 | 01 |
Corsi | ||
---|---|---|
Codice | Titolo | Docente |
01 | Analisi | Mario |
02 | Chimica | Bruni |
04 | Chimica | Verdi |
Studenti | |||
---|---|---|---|
Matricola | Cognome | Nome | DataDiNascita |
6554 | Rossi | Mario | 05/12/1978 |
8765 | Neri | Paolo | 03/11/1976 |
9283 | Verdi | Luisa | 12/11/1978 |
3456 | Rossi | Maria | 01/02/1978 |
Studenti Lavoratori | |||
---|---|---|---|
Matricola | |||
6554 | |||
3456 |
Da Filippo Via Roma 2, Roma | ||
Ricevuta Fiscale 1235 del 12/01/2020 | ||
3 | Coperti | 3,00 |
2 | Antipasti | 6,20 |
3 | Primi | 12,00 |
2 | Bistecche | 18,00 |
- | ||
- | ||
Totale | 39,20 |
Da Filippo Via Roma 2, Roma | ||
Ricevuta Fiscale 1240 del 13/10/2020 | ||
2 | Coperti | 2,00 |
2 | Antipasti | 7,00 |
2 | Primi | 8,00 |
2 | Orate | 20,00 |
2 | Caffè | 2,00 |
- | ||
Totale | 39,00 |
Ricevute | |||||
---|---|---|---|---|---|
Numero | Data | Qtà | Descrizione | Importo | Totale |
1235 | 12/10/2020 | 3 | Coperti | 3,00 | 39,20 |
2 | Antipasti | 6,20 | |||
3 | Primi | 12,00 | |||
2 | Bistecche | 18,00 | |||
1240 | 12/10/2020 | 2 | Coperti | 2,00 | 39,00 |
... | ... | ... |
I valori devono essere semplici
Ricevute | ||
---|---|---|
Numero | Data | Totale |
1235 | 12/10/2020 | 39,20 |
1240 | 12/10/2020 | 39,00 |
Dettaglio | |||
---|---|---|---|
Numero | Qtà | Descrizione | Importo |
1235 | 3 | Coperti | 3,00 |
1235 | 2 | Antipasti | 6,20 |
1235 | 3 | Primi | 12,00 |
1235 | 2 | Bistecche | 18,00 |
1240 | 2 | Coperti | 2,00 |
... | ... | ... | ... |
Dipende da cosa ci interessa:
Ricevute | ||
---|---|---|
Numero | Data | Totale |
1235 | 12/10/2020 | 39,20 |
1240 | 12/10/2020 | 39,00 |
Dettaglio | ||||
---|---|---|---|---|
Numero | Riga | Qtà | Descrizione | Importo |
1235 | 1 | 3 | Coperti | 3,00 |
1235 | 2 | 2 | Antipasti | 6,20 |
1235 | 3 | 3 | Primi | 12,00 |
1235 | 4 | 2 | Bistecche | 18,00 |
1240 | 1 | 2 | Coperti | 2,00 |
... | ... | ... | ... | ... |
Ogni elemento in una tabella può essere o un valore del dominio oppure il valore nullo NULL
Capi di Stato | ||
---|---|---|
Nome | SecondoNome | Cognome |
Franklin | Delano | Roosvelt |
Winston | Churchill | |
Charles | De Gaulle | |
Josip | Stalin |
Studenti | |||
---|---|---|---|
Matricola | Cognome | Nome | DataDiNascita |
6554 | Rossi | Mario | 05/12/1978 |
9283 | Verdi | Luisa | 12/11/1978 |
NULL | Rossi | Maria | 01/02/1978 |
Esami | ||
---|---|---|
Studente | Voto | Corso |
NULL | 30 | NULL |
NULL | 24 | 02 |
9283 | 28 | 01 |
Corsi | ||
---|---|---|
Codice | Titolo | Docente |
01 | Analisi | Mario |
02 | NULL | NULL |
04 | Chimica | Verdi |
Esistono istanze di basi di dati che, pur sintatticamente corrette, non rappresentano informazioni possibili per l’applicazione di interesse.
Studenti | |||
---|---|---|---|
Matricola | Cognome | Nome | |
276545 | Rossi | Mario | |
7876463 | Verdi | Luisa | |
7876463 | Rossi | Maria |
Esami | |||
---|---|---|---|
Studente | Voto | Lode | Corso |
276545 | 32 | 01 | |
276545 | 30 | e lode | 02 |
7876463 | 27 | e lode | 03 |
739430 | 24 | 04 |
Un vincolo è una funzione booleana (un predicato): associa ad ogni istanza il valore vero o falso
Alcuni vincoli (ma non tutti) sono supportati dai DBMS
Studenti | |||
---|---|---|---|
Matricola | Cognome | Nome | |
276545 | Rossi | Mario | |
7876463 | Verdi | Luisa | |
7876463 | Rossi | Maria |
Esami | |||
---|---|---|---|
Studente | Voto | Lode | Corso |
276545 | 32 | 01 | |
276545 | 30 | e lode | 02 |
7876463 | 27 | e lode | 03 |
739430 | 24 | 04 |
Voto ≥ 18 && Voto ≤ 30
Studenti | |||
---|---|---|---|
Matricola | Cognome | Nome | |
276545 | Rossi | Mario | |
7876463 | Verdi | Luisa | |
7876463 | Rossi | Maria |
Esami | |||
---|---|---|---|
Studente | Voto | Lode | Corso |
276545 | 32 | 01 | |
276545 | 30 | e lode | 02 |
7876463 | 27 | e lode | 03 |
739430 | 24 | 04 |
Lode solo se Voto == 30
Stipendi | |||
---|---|---|---|
Impiegato | Lordo | Ritenute | Netto |
Rossi | 55.000 | 12.500 | 42.500 |
Verdi | 45.000 | 10.000 | 35.000 |
Bruni | 47.000 | 11.000 | 36.000 |
Lordo = (Ritenute + Netto)
Studenti | |||
---|---|---|---|
Matricola | Cognome | Nome | |
276545 | Rossi | Mario | |
7876463 | Verdi | Luisa | |
7876463 | Rossi | Maria |
Esami | |||
---|---|---|---|
Studente | Voto | Lode | Corso |
276545 | 32 | 01 | |
276545 | 30 | e lode | 02 |
7876463 | 27 | e lode | 03 |
739430 | 24 | 04 |
Matricola | Cognome | Nome | Corso | Nascita |
---|---|---|---|---|
27655 | Rossi | Mario | Ing inf | 5/12/78 |
78763 | Rossi | Mario | Ing inf | 3/11/76 |
65432 | Neri | Piero | Ing mecc | 10/7/79 |
87654 | Neri | Mario | Ing inf | 3/11/76 |
67653 | Rossi | Piero | Ing mecc | 5/12/78 |
Matricola | Cognome | Nome | Corso | Nascita |
---|---|---|---|---|
27655 | Rossi | Mario | Ing inf | 5/12/78 |
78763 | Rossi | Mario | Ing inf | 3/11/76 |
65432 | Neri | Piero | Ing mecc | 10/7/79 |
87654 | Neri | Mario | Ing inf | 3/11/76 |
67653 | Rossi | Piero | Ing mecc | 5/12/78 |
Matricola è una chiave:
Matricola | Cognome | Nome | Corso | Nascita |
---|---|---|---|---|
27655 | Rossi | Mario | Ing inf | 5/12/78 |
78763 | Rossi | Mario | Ing inf | 3/11/76 |
65432 | Neri | Piero | Ing mecc | 10/7/79 |
87654 | Neri | Mario | Ing inf | 3/11/76 |
67653 | Rossi | Piero | Ing mecc | 5/12/78 |
Cognome, nome, nascita è un'altra chiave:
Matricola | Cognome | Nome | Corso | Nascita |
---|---|---|---|---|
27655 | Rossi | Mario | Ing inf | 5/12/78 |
78763 | Rossi | Mario | Ing Civile | 3/11/76 |
65432 | Neri | Piero | Ing mecc | 10/7/79 |
87654 | Neri | Mario | Ing inf | 3/11/76 |
67653 | Rossi | Piero | Ing mecc | 5/12/78 |
Non ci sono $n$-uple uguali su Cognome e Corso:
Matricola | Cognome | Nome | Corso | Nascita |
---|---|---|---|---|
NULL | NULL | Mario | Ing inf | 5/12/78 |
78763 | Rossi | Mario | Ing inf | 3/11/76 |
65432 | Neri | Piero | Ing mecc | 10/7/79 |
87654 | Neri | Mario | Ing inf | NULL |
NULL | Rossi | Piero | NULL | 5/12/78 |
Matricola | Cognome | Nome | Corso | Nascita |
---|---|---|---|---|
27655 | NULL | Mario | Ing inf | 5/12/78 |
78763 | Rossi | Mario | Ing inf | 3/11/76 |
65432 | Neri | Piero | Ing mecc | 10/7/79 |
87654 | Neri | Mario | Ing inf | NULL |
67653 | Rossi | Piero | NULL | 5/12/78 |
Esami | |||
---|---|---|---|
Studente | Voto | Lode | Corso |
276545 | 32 | 01 | |
276545 | 30 | e lode | 02 |
787643 | 27 | e lode | 03 |
787643 | 24 | 04 |
Studenti | ||
---|---|---|
Matricola | Cognome | Nome |
276545 | Rossi | Mario |
787643 | Neri | Piero |
787642 | Bianchi | Luca |
Esami | |||
---|---|---|---|
Studente | Voto | Lode | Corso |
276545 | 32 | 01 | |
276545 | 30 | e lode | 02 |
787643 | 27 | e lode | 03 |
787647 | 24 | 04 |
Studenti | ||
---|---|---|
Matricola | Cognome | Nome |
276545 | Rossi | Mario |
787643 | Neri | Piero |
787642 | Bianchi | Luca |
Infrazioni | ||||
---|---|---|---|---|
Codice | Data | Vigile | Prov | Targa |
34321 | 1/2/95 | 3987 | MI | 39548K |
53524 | 4/3/95 | 3295 | TO | E39548 |
64521 | 5/4/96 | 3295 | PR | 839548 |
73321 | 5/2/98 | 9345 | PR | 839548 |
Vigili | ||
---|---|---|
Matricola | Cognome | Nome |
3987 | Rossi | Luca |
3295 | Neri | Piero |
9345 | Neri | Mario |
7543 | Mori | Gino |
Infrazioni | ||||
---|---|---|---|---|
Codice | Data | Vigile | Prov | Targa |
34321 | 1/2/95 | 3987 | MI | 39548K |
53524 | 4/3/95 | 3295 | TO | E39548 |
64521 | 5/4/96 | 3295 | PR | 839548 |
73321 | 5/2/98 | 9345 | PR | 839548 |
Auto | |||
---|---|---|---|
Prov | Targa | Cognome | Nome |
MI | 39548K | Rossi | Mario |
TO | E39548 | Rossi | Mario |
PR | 839548 | Neri | Luca |
Un vincolo di integrità referenziale (“foreing key”) fra attributi $X$ di una relazione $r_1$ e un’altra relazione $r_2$ impone ai valori su $X$ in $r_1$ di comparire come valori della chiave primaria di $r_2$
Vigile
della relazione Infrazioni
e la relazione Vigili
Prov
e Numero di Infrazioni
e la relazione Auto
Infrazioni | ||||
---|---|---|---|---|
Codice | Data | Vigile | Prov | Targa |
34321 | 1/2/95 | 3987 | MI | 39548K |
53524 | 4/3/95 | 3295 | TO | E39548 |
64521 | 5/4/96 | 3295 | PR | 839548 |
73321 | 5/2/98 | 9345 | PR | 839548 |
Auto | |||
---|---|---|---|
Prov | Targa | Cognome | Nome |
MI | E39548 | Rossi | Mario |
TO | F34268 | Rossi | Mario |
PR | 839548 | Neri | Luca |
Impiegati | ||
---|---|---|
Matricola | Cognome | Progetto |
34321 | Rossi | IDEA |
53524 | Neri | XYZ |
64521 | Verdi | NULL |
73321 | Bianchi | IDEA |
Progetti | |||
---|---|---|---|
Codice | Inizio | Durata | Costo |
IDEA | 01/2000 | 36 | 200 |
XYZ | 07/2001 | 24 | 120 |
BOH | 09/2001 | 24 | 150 |
Impiegati | ||
---|---|---|
Matricola | Cognome | Progetto |
34321 | Rossi | IDEA |
53524 | Neri | XYZ |
64521 | Verdi | NULL |
73321 | Bianchi | IDEA |
Progetti | |||
---|---|---|---|
Codice | Inizio | Durata | Costo |
IDEA | 01/2000 | 36 | 200 |
XYZ | 07/2001 | 24 | 120 |
BOH | 09/2001 | 24 | 150 |
Impiegati | ||
---|---|---|
Matricola | Cognome | Progetto |
34321 | Rossi | IDEA |
53524 | Neri | NULL |
64521 | Verdi | NULL |
73321 | Bianchi | IDEA |
Progetti | |||
---|---|---|---|
Codice | Inizio | Durata | Costo |
IDEA | 01/2000 | 36 | 200 |
XYZ | 07/2001 | 24 | 120 |
BOH | 09/2001 | 24 | 150 |
Auto | |||
---|---|---|---|
Prov | Targa | Cognome | Nome |
MI | 39548K | Rossi | Mario |
TO | E39548 | Rossi | Mario |
PR | 839548 | Neri | Luca |
Incidenti | |||||
---|---|---|---|---|---|
Codice | Data | ProvA | TargaA | ProvB | TargaB |
34321 | 1/2/95 | TO | E39548 | MI | 39548K |
64521 | 5/4/96 | PR | 839548 | TO | E39548 |
CREATE/DROP/ALTER TABLE/VIEW/INDEX
SELECT
- INSERT
- DELETE
- UPDATE
GRANT
- REVOKE
COMMIT
- ROLLBACK
DECLARE
- OPEN
- FETCH
- CLOSE
SHOW DATABASES;
Ritorna l’elenco dei Database presenti nel DBMS
I comandi possono occupare anche più righe e terminano con il ;
CREATE DATABASE nomeDataBase;
Crea un nuovo DataBase con il nome specificato e lo rende accessibile all’utente ROOT.
CREATE DATABASE IF NOT EXISTS nomeDataBase;
Crea il DB solo se non esiste già
DROP DATABASE [IF EXISTS] nomeDataBase;
usiamo [...]
per indicare le parti opzionali dei
comandi.
USE nomeDataBase;
Tutti i comandi ora saranno riferiti a questo DB.
Istruzione CREATE TABLE
;
specifica attributi, domini e vincoli
CREATE TABLE [IF NOT EXISTS] nomeTabella(
nomeAttributo1 tipo,
attributo2 tipo,
...
attributoN tipo
)
Tipo | Byte | Minimo | Massimo |
---|---|---|---|
TINYINT | 1 | $-128$ | $127$ |
SMALLINT | 2 | $-32768$ | $32767$ |
MEDIUMINT | 3 | $-8388608$ | 8388607 |
INT | 4 | $-2147483648$ | $2147483647$ |
BIGINT | 8 | $-2^{63}$ | $2^{63}-1$ |
INT(N)
: suggeriamo al motore di usare N
caratteri per mostrare il dato; es: INT(11)
numeric(i,n)
salva esattamente n
cifre decimalidecimal(i,n)
salva almeno n
cifre decimaliTipo | Descrizione |
---|---|
CHAR | Stringa di lunghezza fissa non binaria |
VARCHAR | Stringa di lunghezza variabile non binaria |
BINARY | Sequenza binaria a lunghezza fissa |
VARBINARY | Sequenza binaria a lunghezza variabile |
Tipo | Descrizione |
---|---|
TINYBLOB | Binary Large OBject piccolo |
BLOB | Binary Large OBject |
MEDIUMBLOB | Binary Large OBject medio |
LONGBLOB | Binary Large OBject grande |
Tipo | Descrizione |
---|---|
TINYTEXT | Stringa non binaria piccola |
TEXT | Stringa non binaria |
MEDIUMTEXT | Stringa non binaria medio |
LONGTEXT | Stringa non binaria grande |
YEAR
- anno nel formato YYYY
DATE
- data nel formato YYYY-MM-DD
TIME
- tempo nel formato hh:mm:ss
DATETIME
- tempo nel formato YYYY-MM-DD hh:mm:ss
TIMESTAMP
- come DATETIME
, ma si aggiorna da soloTipo | Descrizione |
---|---|
GEOMETRY | Valore spaziale di qualsiasi tipo |
POINT | Coordinate X, Y |
LINESTRING | Curva (uno o più POINT) |
POLYGON | Un poligono |
… e molti altri
lunghezza + 1
; posso indicare una lunghezza massimavalore | CHAR(4) | spazio | VARCHAR(4) | spazio |
---|---|---|---|---|
'' |
'____' |
4 byte | '' |
1 byte |
'ab' |
'ab__' |
4 byte | 'ab' |
3 byte |
'abcd' |
'abcd' |
4 byte | 'abcd' |
5 byte |
'abcdef' |
'abcd' |
4 byte | 'abcd' |
5 byte |
Studenti | |||
---|---|---|---|
Matricola | Cognome | Nome | |
276545 | Rossi | Mario | |
7876463 | Neri | Piero | |
7876462 | Bianchi | Luca |
Corsi | ||
---|---|---|
Codice | Titolo | Docente |
01 | Analisi | Mario |
02 | Chimica | Bruni |
04 | Chimica | Verdi |
Esami | |||
---|---|---|---|
Studente | Voto | Lode | Corso |
276545 | 32 | 01 | |
276545 | 30 | e lode | 02 |
7876463 | 27 | e lode | 03 |
7876463 | 24 | 04 |
Studenti | |||
---|---|---|---|
Matricola | Cognome | Nome | |
276545 | Rossi | Mario | |
7876463 | Neri | Piero | |
7876462 | Bianchi | Luca |
CREATE TABLE Studenti(
matricola int(11),
cognome varchar(45),
nome varchar(45)
);
DROP TABLE [IF EXISTS] nomeTabella;
… intuitivo
DROP TABLE [IF EXISTS] nomeTabella1,
nomeTabella2,
nomeTabella3,
...;
Posso definire dei vincoli:
PRIMARY KEY
- chiave primaria (una sola, implica NOT NULL
)NOT NULL
UNIQUE
- definisce chiaviCHECK
- vedremo più avantiStudenti | |||
---|---|---|---|
Matricola | Cognome | Nome | |
276545 | Rossi | Mario | |
7876463 | Neri | Piero | |
7876462 | Bianchi | Luca |
CREATE TABLE Studenti(
matricola int(11) PRIMARY KEY,
cognome varchar(45),
nome varchar(45)
);
Studenti | |||
---|---|---|---|
Matricola | Cognome | Nome | |
276545 | Rossi | Mario | |
7876463 | Neri | Piero | |
7876462 | Bianchi | Luca |
CREATE TABLE Studenti(
matricola int(11),
cognome varchar(45),
nome varchar(45),
PRIMARY KEY (matricola)
);
Studenti | |||
---|---|---|---|
Matricola | Cognome | Nome | |
276545 | Rossi | Mario | |
7876463 | Neri | Piero | |
7876462 | Bianchi | Luca |
CREATE TABLE Studenti(
matricola int(11) PRIMARY KEY,
cognome varchar(45) NOT NULL,
nome varchar(45) NOT NULL
);
Corsi | ||
---|---|---|
Codice | Titolo | Docente |
01 | Analisi | Mario |
02 | Chimica | Bruni |
04 | Chimica | Verdi |
CREATE TABLE Corsi(
codice int(11) PRIMARY KEY,
titolo varchar(45) NOT NULL,
docente varchar(45)
);
Esami | |||
---|---|---|---|
Studente | Voto | Lode | Corso |
276545 | 32 | 01 | |
276545 | 30 | e lode | 02 |
7876463 | 27 | e lode | 03 |
7876463 | 24 | 04 |
CREATE TABLE Esami(
studente int(11) PRIMARY KEY,
voto smallint NOT NULL,
lode bool,
corso int(11) PRIMARY KEY
);
Esami | |||
---|---|---|---|
Studente | Voto | Lode | Corso |
276545 | 32 | 01 | |
276545 | 30 | e lode | 02 |
7876463 | 27 | e lode | 03 |
7876463 | 24 | 04 |
CREATE TABLE Esami(
studente int(11),
voto smallint NOT NULL,
lode bool,
corso int(11),
PRIMARY KEY (studente, corso)
);
CREATE TABLE Corsi(
codice int(11) NOT NULL UNIQUE,
titolo varchar(45) NOT NULL,
docente varchar(45)
);
CREATE TABLE Esami(
studente int(11) NOT NULL UNIQUE,
voto smallint NOT NULL,
lode bool,
corso int(11) NOT NULL UNIQUE
);
In general, a unique constraint is violated when there is more than one row in the table where the values of all of the columns included in the constraint are equal. However, two null values are not considered equal in this comparison. That means even in the presence of a unique constraint it is possible to store duplicate rows that contain a null value in at least one of the constrained columns. This behavior conforms to the SQL standard, but we have heard that other SQL databases might not follow this rule. So be careful when developing applications that are intended to be portable.
PostgreSQL Manual
CREATE TABLE nomeTabella (
id int(11) PRIMARY KEY,
campo1 int(19),
campo2 int(12),
CONSTRAINT [nome] UNIQUE(campo1, campo2)
);
ottimo come chiave primaria!
CREATE TABLE Studenti(
matricola int(11) PRIMARY KEY AUTO_INCREMENT,
cognome varchar(45),
nome varchar(45)
);
CREATE TABLE nome(
nomeAttributo tipo DEFAULT valore
);
CREATE TABLE Corsi(
codice int(11) PRIMARY KEY,
titolo varchar(45) NOT NULL DEFAULT "nuovo",
docente varchar(45)
);
CREATE TABLE nome(
nomeAttributo tipo COMMENT "commento"
);
CREATE TABLE Corsi(
codice int(11) PRIMARY KEY,
titolo varchar(45) NOT NULL
COMMENT "Titolo del corso",
docente varchar(45)
);
Software | |||
---|---|---|---|
Modulo | Versione | Tipo | Data |
Esse3 | 1.00 | alfa | 10/10/2014 |
Esse3 | 1.00 | beta | 10/10/2014 |
Esse3 | 1.00 | NULL | 16/11/2014 |
Esse3 | 1.02 | alfa | 18/12/2014 |
Esse4 | 1.00 | alfa | 12/01/2015 |
Modulo, Versione e Tipo sono una PK?
Software | |||
---|---|---|---|
Modulo | Versione | Tipo | Data |
Esse3 | 1.00 | alfa | 10/10/2014 |
Esse3 | 1.00 | beta | 14/11/2014 |
Esse3 | 1.00 | NULL | 16/11/2014 |
Esse3 | 1.02 | alfa | 18/12/2014 |
Esse4 | 1.00 | alfa | 12/01/2015 |
Software | |||
---|---|---|---|
Modulo | Versione | Tipo | Data |
Esse3 | 1.00 | alfa | 10/10/2014 |
Esse3 | 1.00 | beta | 14/11/2014 |
Esse3 | 1.00 | '' | 16/11/2014 |
Esse3 | 1.02 | alfa | 18/12/2014 |
Esse4 | 1.00 | alfa | 12/01/2015 |
FOREIGN KEY
e REFERENCES
e permettono
di definire vincoli di integrità referenzialecolonne che sono FK
colonne nella relazione (tabella) esterna
Studenti | |||
---|---|---|---|
Matricola | Cognome | Nome | |
276545 | Rossi | Mario | |
7876463 | Neri | Piero | |
7876462 | Bianchi | Luca |
Corsi | ||
---|---|---|
Codice | Titolo | Docente |
01 | Analisi | Mario |
02 | Chimica | Bruni |
04 | Chimica | Verdi |
Esami | |||
---|---|---|---|
Studente | Voto | Lode | Corso |
276545 | 32 | 01 | |
276545 | 30 | e lode | 02 |
7876463 | 27 | e lode | 03 |
7876463 | 24 | 04 |
CREATE TABLE Esami(
studente int(11),
voto smallint NOT NULL,
lode bool,
corso int(11),
PRIMARY KEY (studente, corso),
FOREIGN KEY (studente) REFERENCES Studenti(matricola)
);
Non funziona ovunque (MySql)
CREATE TABLE Esami(
studente int(11) REFERENCES Studenti(matricola),
voto smallint NOT NULL,
lode bool,
corso int(11),
PRIMARY KEY (studente, corso)
);
CREATE TABLE Esami(
studente int(11),
voto smallint NOT NULL,
lode bool,
corso int(11),
PRIMARY KEY (studente, corso),
FOREIGN KEY (studente) REFERENCES Studenti(matricola)
FOREIGN KEY (corso) REFERENCES Corsi(codice)
);
CREATE TABLE Esami(
studente int(11),
voto smallint NOT NULL,
lode bool,
corso int(11),
PRIMARY KEY (studente, corso),
CONSTRAINT FK_Studente FOREIGN KEY (studente) REFERENCES Studenti(matricola)
CONSTRAINT FK_Corso FOREIGN KEY (corso) REFERENCES Corsi(codice)
);
SET foreign_key_checks = 0
SET foreign_key_checks = 1
Infrazioni | ||||
---|---|---|---|---|
Codice | Data | Vigile | Prov | Targa |
34321 | 1/2/95 | 3987 | MI | 39548K |
53524 | 4/3/95 | 3295 | TO | E39548 |
64521 | 5/4/96 | 3295 | PR | 839548 |
73321 | 5/2/98 | 9345 | PR | 839548 |
Automobile | |||
---|---|---|---|
Prov | Targa | Cognome | Nome |
MI | 39548K | Rossi | Mario |
TO | E39548 | Rossi | Mario |
PR | 839548 | Neri | Luca |
Vigili | ||
---|---|---|
Matricola | Cognome | Nome |
3987 | Rossi | Luca |
3295 | Neri | Piero |
9345 | Neri | Mario |
7543 | Mori | Gino |
Vigili | ||
---|---|---|
Matricola | Cognome | Nome |
3987 | Rossi | Luca |
3295 | Neri | Piero |
9345 | Neri | Mario |
7543 | Mori | Gino |
CREATE TABLE Vigili(
matricola int(11) PRIMARY KEY AUTO_INCREMENT,
cognome varchar(45) NOT NULL,
nome varchar(45) NOT NULL
);
Automobile | |||
---|---|---|---|
Prov | Targa | Cognome | Nome |
MI | 39548K | Rossi | Mario |
TO | E39548 | Rossi | Mario |
PR | 839548 | Neri | Luca |
CREATE TABLE Automobile(
prov char(2),
targa char(6),
cognome varchar(45) NOT NULL,
nome varchar(45) NOT NULL,
PRIMARY KEY (prov, targa)
);
Infrazioni | ||||
---|---|---|---|---|
Codice | Data | Vigile | Prov | Targa |
34321 | 1/2/95 | 3987 | MI | 39548K |
53524 | 4/3/95 | 3295 | TO | E39548 |
64521 | 5/4/96 | 3295 | PR | 839548 |
73321 | 5/2/98 | 9345 | PR | 839548 |
CREATE TABLE Infrazioni(
codice int(11) PRIMARY KEY AUTO_INCREMENT,
data datetime,
vigile int(11),
prov char(2),
targa char(6),
FOREIGN KEY (vigile) REFERENCES Vigili(matricola),
FOREIGN KEY (prov, targa)
REFERENCES Automobile(prov, targa)
);
CREATE TABLE Infrazioni(
codice int(11) PRIMARY KEY AUTO_INCREMENT,
data datetime NOT NULL,
vigile int(11),
prov char(2) NOT NULL,
targa char(6) NOT NULL,
FOREIGN KEY (vigile) REFERENCES Vigili(matricola)
ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY (prov, targa) REFERENCES
Automobile(prov, targa)
);
Infrazioni | |||||
---|---|---|---|---|---|
Codice | Data | dataModifica | Vigile | Prov | Targa |
34321 | 1/2/95 | 1/2/95 | 3987 | MI | 39548K |
53524 | 4/3/95 | 16/4/91 | 3295 | TO | E39548 |
64521 | 5/4/96 | 11/2/84 | 3295 | PR | 839548 |
73321 | 5/2/98 | 31/12/98 | 9345 | PR | 839548 |
DROP
tabellaALTER TABLE nomeTabella
azione1
[, azione2, ...]
ALTER TABLE nomeTabella
ADD COLUMN definizioneColonna
[ FIRST | AFTER nomeColonna ]
ALTER TABLE Infrazioni
ADD COLUMN dataModifica TIMESTAMP
AFTER data
ALTER TABLE nomeTabella
DROP COLUMN nomeColonna
ALTER TABLE infrazioni
DROP COLUMN dataModifica
ALTER TABLE nomeTabella
CHANGE COLUMN nomeOriginale
nomeNuovo tipo
ALTER TABLE infrazioni
CHANGE COLUMN dataModifica
dataUltimaModifica TIMESTAMP
ALTER TABLE automobili
CHANGE COLUMN cognome
VARCHAR(100)
ALTER TABLE nomeTabella
RENAME TO nuovoNome
ALTER TABLE infrazioni
RENAME TO odiateInfrazioni
ALTER TABLE nomeTabella
ADD CONSTRAINT nome
FOREIGN KEY (...)
REFERENCES tabella(...)
ALTER TABLE nomeTabella
DROP FOREIGN KEY nome
https://www.mysqltutorial.org/getting-started-with-mysql/mysql-sample-database/
SELECT * FROM products;
SELECT attributo1 [, attributo2, ...]
FROM tabella1 [, tabella2, ...]
[WHERE condizione]
*
= tutti gli attributiFROM
= da dove (per ora)WHERE
= quali ennupleWHERE
SELECT * FROM products WHERE MSRP < 75;
SELECT productName, buyPrice, MSRP
FROM products
WHERE MSRP < 75;
AS
SELECT productName AS nomeProdotto,
productVendor AS nomeVenditore
FROM products;
SELECT productName, buyPrice, MSRP
FROM products
WHERE MSRP < 75;
in realtà stiamo scrivendo
SELECT p.productName, p.buyPrice, p.MSRP
FROM products p
WHERE p.MSRP < 75;
SELECT * FROM products;
in realtà stiamo scrivendo
SELECT productCode, productName, productLine,
productScale, productVendor,
productDescription, quantityInStock,
buyPrice, MSRP
FROM products;
SELECT * FROM products;
in realtà stiamo scrivendo
SELECT productCode, productName, productLine,
productScale, productVendor,
productDescription, quantityInStock,
buyPrice, MSRP
FROM products
WHERE true;
SELECT * FROM employees
WHERE firstName = 'Leslie';
"Leslie"
o 'Leslie'
?
'Leslie'
Ci'ao
" "
: "Ci'ao"
' '
: raddoppio → 'Ci''ao'
Ci"'"ao
" "
: raddoppio → "Ci""ao"
' '
: 'Ci"ao'
SELECT * FROM employees
WHERE lastName LIKE '%son';
SELECT * FROM employees
WHERE lastName NOT LIKE '%son';
%
= zero o più caratteri_
= esattamente un carattere%
uso \%
_
uso \_
SELECT * FROM payments
WHERE amount BETWEEN 5000 AND 8000;
forma equivalente
SELECT officeCode, city, phone
FROM offices
WHERE country IN ('USA', 'FRANCE');
forma equivalente
SELECT officeCode, city, phone
FROM offices
WHERE country = 'USA' OR
country = 'FRANCE';
SELECT ... FROM ...
WHERE colonna = "";
SELECT ... FROM ...
WHERE colonna IS NULL;
length()
reverse()
right()
trim()
day()
year()
now()
month()
monthname()
SELECT ... FROM ... WHERE ...
ORDER BY col1 [ASC|DESC], col2 [ASC|DESC], ...
ASC
: crescente → DEFAULT!DESC
: decrescenteFIELD(text, str1, str2, str3, ...)
Ritorna la posizione della stringa text
nella lista str1
, str2
, str3
, …
SELECT DISTINCT ... FROM ...
SELECT ... FROM tabella1, tabella2, ...
Risultato: una riga per ogni combinazione di valori tra le righe di tabella1 e di tabella2
impiegati e quella dei clienti
SELECT * FROM customers, employees;
impiegati e quella dei clienti
SELECT * FROM customers, employees;
Forma esplicita:
SELECT * FROM customers CROSS JOIN employees;
SELECT ... FROM tabella1, tabella2, ...
WHERE condizione sui valori comuni (PK e FK)
Creo una riga per ogni combinazione di valori tra le righe della tabella1 e della tabella2, ma poi salvo solo quelle sensate
SELECT customerName, salesRepEmployeeNumber,
lastName, employeeNumber
FROM customers, employees
WHERE salesRepEmployeeNumber = employeeNumber
SELECT ... FROM tabella1
INNER JOIN tabella2
ON PK = FK
SELECT ... FROM tabella1
INNER JOIN tabella2
ON tabella2.PK = tabella1.FK
SELECT productCode, productName, textDescription
FROM products INNER JOIN productlines
ON products.productline = productlines.productline;
SELECT productCode, productName, textDescription
FROM products p1
INNER JOIN productlines p2
ON p1.productline = p2.productline;
SELECT productCode, productName, textDescription
FROM products INNER JOIN productlines
ON products.productline =
productlines.productline;
SELECT productCode, productName,
textDescription
FROM products INNER JOIN productlines
USING(productline);
Se gli unici nomi di attributi in comune tra due tabelle sono quelli di FK/PK, si può usare una forma ANCORA più abbreviata
SELECT ... FROM tabella1
NATURAL JOIN tabella2
Cosa succede se aggiungo/cambio colonne?
SELECT ... FROM tabella1
LEFT OUTER JOIN tabella2
ON PK = FK
SELECT customerName, concat(firstName,' ',lastName)
FROM customers LEFT OUTER JOIN employees
ON salesRepEmployeeNumber = employeeNumber
forma equivalente
SELECT customerName, concat(firstName,' ',lastName)
FROM customers LEFT JOIN employees
ON salesRepEmployeeNumber = employeeNumber
Inner
Left Outer
SELECT c.customerNumber, c.customerName,
o.orderNumber, o.status
FROM customers c LEFT JOIN orders o
ON c.customerNumber = o.customerNumber;
SELECT ... FROM tabella1
RIGHT OUTER JOIN tabella2
ON PK = FK
Inner
Left Outer
Right Outer
SELECT ... FROM tabella1
[INNER|LEFT|RIGHT]JOIN tabella2
ON PK = FK
[INNER|LEFT|RIGHT]JOIN tabella3
ON PK = FK
Inner + Inner
Inner + Left Outer
ID | Nome | Prezzo | Linea |
---|---|---|---|
1 | Audi A5 | 50,00 | A |
2 | Mercedes C | 45,00 | A |
3 | Smart | 25,00 | B |
ID | Nome | Link |
---|---|---|
A | Auto Sportive | ... |
B | Micro Auto | ... |
ID | Nome | Prezzo | Linea | ID | Nome | Link |
---|---|---|---|---|---|---|
1 | Audi A5 | 50,00 | A | A | Auto Sportive | ... |
1 | Audi A5 | 50,00 | A | B | Micro Auto | ... |
2 | Mercedes C | 45,00 | A | A | Auto Sportive | ... |
2 | Mercedes C | 45,00 | A | B | Micro Auto | ... |
3 | Smart | 25,00 | B | A | Auto Sportive | ... |
3 | Smart | 25,00 | B | B | Micro Auto | ... |
ID | Nome | Prezzo | Linea |
---|---|---|---|
1 | Audi A5 | 50,00 | A |
2 | Mercedes C | 45,00 | A |
3 | Smart | 25,00 | B |
ID | Nome | Link |
---|---|---|
A | Auto Sportive | ... |
B | Micro Auto | ... |
ID | Nome | Prezzo | Linea | ID | Nome | Link |
---|---|---|---|---|---|---|
1 | Audi A5 | 50,00 | A | A | Auto Sportive | ... |
2 | Mercedes C | 45,00 | A | A | Auto Sportive | ... |
3 | Smart | 25,00 | B | B | Micro Auto | ... |
ID | Nome | Prezzo | Linea |
---|---|---|---|
1 | Audi A5 | 50,00 | A |
2 | Mercedes C | 45,00 | NULL |
3 | Smart | 25,00 | B |
ID | Nome | Link |
---|---|---|
A | Auto Sportive | ... |
B | Micro Auto | ... |
ID | Nome | Prezzo | Linea | ID | Nome | Link |
---|---|---|---|---|---|---|
1 | Audi A5 | 50,00 | A | A | Auto Sportive | ... |
3 | Smart | 25,00 | B | B | Micro Auto | ... |
ID | Nome | Prezzo | Linea |
---|---|---|---|
1 | Audi A5 | 50,00 | A |
2 | Mercedes C | 45,00 | NULL |
3 | Smart | 25,00 | B |
ID | Nome | Link |
---|---|---|
A | Auto Sportive | ... |
B | Micro Auto | ... |
ID | Nome | Prezzo | Linea | ID | Nome | Link |
---|---|---|---|---|---|---|
1 | Audi A5 | 50,00 | A | A | Auto Sportive | ... |
2 | Mercedes C | 45,00 | NULL | NULL | NULL | NULL |
3 | Smart | 25,00 | B | B | Micro Auto | ... |
ID | Nome | Colore | Linea |
---|---|---|---|
1 | Audi A5 | 1 | A |
2 | Mercedes C | 2 | A |
3 | Smart | 2 | B |
ID | Nome | Link |
---|---|---|
A | Auto Sportive | ... |
B | Micro Auto | ... |
ID | Colore |
---|---|
1 | Rosso |
2 | Blu |
ID | Nome | Prezzo | Linea | ID | Nome | Link | ||
---|---|---|---|---|---|---|---|---|
1 | Audi A5 | 1 | A | A | Auto Sportive | ... | 1 | Rosso |
2 | Mercedes C | 2 | A | A | Auto Sportive | ... | 2 | Blu |
3 | Smart | 2 | B | B | Micro Auto | ... | 2 | Blu |
SELECT ... FROM tabella1
FULL OUTER JOIN tabella2
ON PK = FK
ID | Veicolo | Colore | Persona |
---|---|---|---|
1 | Automobile | 1 | 4 |
2 | Bici | 2 | NULL |
3 | Moto | NULL | 1 |
4 | Scooter | 3 | 3 |
ID | Cognome |
---|---|
1 | Rossi |
2 | Bianchi |
3 | Bassi |
4 | Scaini |
ID | Colore |
---|---|
1 | Verde |
2 | Giallo |
3 | Blu |
Persone che possiedono veicoli colorati
SELECT v.veicolo, c.colore, p.cognome
FROM veicolo v
INNER JOIN persona p ON v.id = p.id
INNER JOIN colore c ON v.colore = c.id ;
Veicolo | Colore | Cognome |
---|---|---|
Automobile | Verde | Scaini |
Scooter | Blu | Bassi |
ID | Veicolo | Colore | Persona |
---|---|---|---|
1 | Automobile | 1 | 4 |
2 | Bici | 2 | NULL |
3 | Moto | NULL | 1 |
4 | Scooter | 3 | 3 |
ID | Cognome |
---|---|
1 | Rossi |
2 | Bianchi |
3 | Bassi |
4 | Scaini |
ID | Colore |
---|---|
1 | Verde |
2 | Giallo |
3 | Blu |
Persone che possiedono veicoli colorati o nessun veicolo
SELECT v.veicolo, c.colore, p.cognome
FROM persona p
LEFT JOIN veicolo ON v.id = p.id
INNER JOIN colore c ON v.colore = c.id ;
Veicolo | Colore | Cognome |
---|---|---|
Automobile | Verde | Scaini |
Scooter | Blu | Bassi |
ID | Veicolo | Colore | Persona |
---|---|---|---|
1 | Automobile | 1 | 4 |
2 | Bici | 2 | NULL |
3 | Moto | NULL | 1 |
4 | Scooter | 3 | 3 |
ID | Cognome |
---|---|
1 | Rossi |
2 | Bianchi |
3 | Bassi |
4 | Scaini |
ID | Colore |
---|---|
1 | Verde |
2 | Giallo |
3 | Blu |
Persone che possiedono veicoli colorati o nessun veicolo
SELECT v.veicolo, c.colore, p.cognome
FROM veicolo v
INNER JOIN colore c ON v.colore = c.id
RIGHT JOIN persona p ON v.id = p.id;
Veicolo | Colore | Cognome |
---|---|---|
Automobile | Verde | Scaini |
Scooter | Blu | Bassi |
Rossi | NULL | NULL |
Bianchi | NULL | NULL |
SELECT ... FROM tabella1
[LEFT|RIGHT|INNER] JOIN tabella1
ON PK = FK
employeeNumber | firstName | lastName | reportsTo |
---|---|---|---|
1002 | Diane | Murphy | NULL |
1056 | Mary | Patterson | 1002 |
1076 | Jeff | Firrelli | 1056 |
1088 | William | Patterson | 1056 |
SELECT c1.city, c1.customerName,c2.customerName
FROM customers c1 INNER JOIN customers c2
ON c1.city = c2.city AND
c1.customername <> c2.customerName
forma equivalente
SELECT c1.city, c1.customerName,c2.customerName
FROM customers c1 INNER JOIN customers c2
ON c1.city = c2.city
WHERE c1.customername <> c2.customerName
SELECT ... FROM ...
UNION [DISTINCT | ALL]
SELECT ... FROM ...
[UNION [DISTINCT | ALL]
SELECT ... FROM ...]
SELECT ... FROM ...
UNION [DISTINCT | ALL]
SELECT ... FROM ...
[UNION [DISTINCT | ALL]
SELECT ... FROM ...]
DISTINCT
: default, elimina duplicatiALL
: se specificato, NON elimina duplicatiSELECT customerNumber,contactLastname
FROM customers
UNION
SELECT employeeNumber, firstname
FROM employees;
SELECT customerNumber AS id,
contactLastname AS name, "Cliente" AS tipo
FROM customers
UNION
SELECT employeeNumber AS id,
concat(firstname," ",lastname) AS name,
"Impiegato" AS tipo
FROM employees;
SELECT ... FROM ...
UNION [DISTINCT | ALL]
SELECT ... FROM ...
ORDER BY criteri
(SELECT ... FROM ...)
UNION [DISTINCT | ALL]
(SELECT ... FROM ...)
ORDER BY criteri
SELECT ... FROM ...
INTERSECT
SELECT ... FROM ...
INTERSECT
SELECT ... FROM ...
Non c’è in MySql, servono query nidificate
SELECT a1 , a2 ,...,an
FROM tabella1 WHERE condizioni
GROUP BY a1, a2,...,an
SELECT status
FROM orders
GROUP BY status
SELECT status
FROM orders
WHERE orderDate < "2003-12-31"
GROUP BY status;
forma equivalente
SELECT DISTINCT status
FROM orders
WHERE orderDate < "2003-12-31"
SELECT a1, a2, ..., an, aggregatore(ax)
FROM tabella1 WHERE condizioni
Esempio:
SELECT a1, a2, ..., an, aggregatore(ax)
FROM tabella1 WHERE condizioni
Aggregatori:
COUNT
: conta il numero di valori presentiSUM
: somma dei valoriAVG
: media dei valoriMAX
/MIN
: massimo e minimoDifferenza fra
SELECT count(*)
FROM employees
e
SELECT count(reportsTo)
FROM employees
SELECT count( distinct reportsTo)
FROM employees;
SELECT avg(MSRP), productName
FROM products
SELECT a1, a2 , ... , an, aggregatore(ax)
FROM tabella1 WHERE condizioni
GROUP BY a1, a2, ... ,an
date_part('month', attributo)
date_part('month', attributo)
date_part('year', attributo)
Un passo alla volta:
Un passo alla volta:
SELECT amount*-1, paymentDate FROM payments
WHERE customerNumber = 124
UNION
SELECT sum(quantityOrdered*priceEach),orderDate
FROM orderdetails INNER JOIN orders
USING (orderNumber)
WHERE customerNumber = 124
GROUP BY orderNumber
ORDER BY paymentDate;
SELECT a1, a2, ... ,an, aggregatore(ax)
FROM tabella1 WHERE condizioni
GROUP BY a1, a2, ... ,an
HAVING condizioniAggregate
Hint: ordini spediti hanno status "Shipped"
SELECT ordernumber, status,
SUM(quantityOrdered*priceeach) total
FROM orderdetails
INNER JOIN orders USING(ordernumber)
GROUP BY ordernumber
HAVING status <> 'Shipped' AND total < 10000;
forma equivalente
SELECT ordernumber, status,
SUM(quantityOrdered*priceeach) total
FROM orderdetails
INNER JOIN orders USING(ordernumber)
WHERE status <> 'Shipped'
GROUP BY ordernumber
HAVING total < 10000;
SELECT a1,a2,...,an,(QUERY singolo val.)
FROM (QUERY)
WHERE a1 > (QUERY singolo val.)
AND a2 IN (QUERY singolo attrib.)
Per adesso:
Hint: subquery nella clausola SELECT
Hint: subquery nella clausola WHERE
Hint: subquery nella clausola WHERE ... NOT IN
SELECT customername
FROM customers
WHERE customerNumber NOT IN
(SELECT DISTINCT customernumber
FROM orders);
forma equivalente
SELECT customername
FROM customers
LEFT JOIN orders USING (customerNumber)
WHERE orderNumber IS NULL;
Hint: creare prima la query che somma le righe dell’ordine
Finora:
SELECT a1,a2,...,an
FROM tab1 WHERE
a1 > (SELECT c1
FROM tab2
WHERE tab2.c2 > tab1.a1)
SELECT a1,a2,...,an
FROM tab
WHERE EXISTS (QUERY singolo val.)
SELECT a1,a2,...,an
FROM tab
WHERE ...
LIMIT numero
SELECT a1,a2,...,an
FROM tab
WHERE ...
LIMIT X, N
INSERT INTO tabella(col1, col2, ...)
VALUES (valore1, valore2, ...)
[, (valore1, valore2, ...), ...]
AUTO_INCREMENT: NULL
Hint: INSERT INTO tabella (col1,col2,...) VALUES (valore1,valore2,...)
INSERT INTO tabella(col1, col2, ...)
SELECT ...
Il risultato della SELECT
deve fornire:
creare l’ordine 10426 (a mano, tabella orders)
Hint: INSERT INTO tabella (col1,col2,...) VALUES (valore1,valore2,...)
prendere tutte le righe di 10425 (orderdetails)
Hint: conta l'ordine delle colonne, vi servirà FK 10426
inserire tutte queste $n$-uple nella tabella (orderdetails)
Hint: INSERT INTO tabella (col1,col2,...) SELECT ...
UPDATE tabella
SET col1 = valore1
[, col2 = val2...]
[WHERE condizione]
WHERE
, aggiorno tutte le $n$-uple della tabellaImpiegato 1056, mettete una email a scelta
Hint: UPDATE tabella SET col1 = valore1 WHERE condizione
Hint: UPDATE tabella SET col1 = valore1 WHERE condizione
Hint: UPDATE tabella SET col1 = valore1 WHERE condizione
Individuare i clienti senza venditore
Trovare l'agente con matricola più alta
Hint: venditore ha `jobTitle = 'Sales Rep'`
Aggiornare i dati
UPDATE tabella
SET col1 = col1 +1, col2 = col1
col1
col1
DELETE FROM tabella
[WHERE condizioni]
oppure
DELETE FROM tabella
[WHERE condizioni]
SELECT *
per vedere che succedeHint: DELETE FROM tab WHERE ...
Opzioni di MySql WorkBench:
Error Code: 1175. You are using safe update
mode and you tried to update a table without
a WHERE that uses a KEY column To disable
safe mode, toggle the option in Preferences ->
SQL Queries and reconnect.
Vincoli interrelazionali:
Error executing SQL statement.
ERROR: update or delete on table "customers" violates foreign key constraint "orders_ibfk_1" on table "orders"
Dettaglio: Key (customernumber)=(249) is still referenced from table "orders". - Connection: PostgreSQL: 2ms
Devo prima modificare le altre tabelle!
CREATE TABLE nomeTab(
attr1 tipo1 CHECK (condizione),
attr2 tipo2,...,
CHECK (condizione))
stipendio inferiore a quello del capo
CREATE TABLE Impiegato(
matricola integer,
cognome character(20),
sesso character NOT NULL
CHECK (sesso in (‘M’,‘F’)),
stipendio integer, superiore integer,
CHECK (stipendio <=
(SELECT stipendio
FROM Impiegato J
WHERE superiore = J.matricola))
CREATE ASSERTION nome CHECK (condizione)
Stesse note del check
CREATE ASSERTION AlmenoUnImpiegato
CHECK ((SELECT count(*) FROM Impiegato) >= 1)
SET @variabile = valore;
SELECT @variabile;
SET @pippo = 'Hello, World!';
SELECT @pippo;
SET @prezzo = (SELECT max(msrp)
FROM products);
SELECT @prezzo;
SELET * FROM products
WHERE MSRP = @prezzo;
Cosa accade quando invio una query al server?
E se devo eseguire spesso la stessa query??
SET profiling = 1;
esecuzione comandi
SHOW PROFILES;
SHOW PROFILE [FOR QUERY n];
SET profiling = 0;
SHOW PROFILES
: storico dei tempi di esecuzioneSHOW PROFILE
: come ho impiegato il tempo nell’ultima query/query specificata?Tipo
ALL
: tutte le informazioniCPU
: tempo CPU per user/systemSWAPS
: utilizzo della memoria su discoSOURCE
: nome della funzione/libreria usatiSHOW PROFILE ALL FOR QUERY 4;
PREPARE nomeStatement FROM 'query';
EXECUTE nomeStatement USING p1, p2,...;
DEALLOCATE PREPARE nomeStatement;
PREPARE
: crea una query riutilizzabile, che può ricevere parametriEXECUTE
: esegue il comando salvatoDEALLOCATE PREPARE
: elimina il comandoPREPARE nomeStatement FROM
'SELECT a1,a2,...
FROM tabella
WHERE a1 = ? AND a2 = ?';
PREPARE nomeStatement(type1, type2, ...) AS
SELECT a1,a2,...
FROM tabella
WHERE a1 = $1 AND a2 = $2;
$
Hint: PREPARE nomeStatement FROM 'SELECT a1,a2,... FROM tabella WHERE a1 = ? AND a2 = ?';
PREPARE stmt1 FROM
'SELECT productCode, productName FROM products
WHERE MSRP > ?';
EXECUTE nomeStatement
[USING @var1, @var2,...];
EXECUTE nomeStatement(arg1, arg2, ...);
Hint: EXECUTE nomeStatement
[USING @var1, @var2,...];
SET @MSRP = 100;
EXECUTE stmt1 USING @MSRP;
DEALLOCATE PREPARE nomeStatement;
DROP PREPARE nomeStatement;
PREPARE stmtListinoClienti FROM
'SELECT productCode, productName, MSRP FROM products';
Problemi:
MERGE (predefinito)
TEMPTABLE (materialized)
CREATE VIEW nomeVista AS
SELECT ...
Dettagli:
CREATE VIEW viewListinoClienti AS
SELECT productCode, productName, MSRP
FROM products;
SELECT * from viewListinoClienti;
Hint: CREATE VIEW nomeVista AS
SELECT ...
CREATE VIEW viewTotaleOrdini AS
SELECT orderNumber,
SUM(quantityOrdered * priceEach) total
FROM orderdetails
GROUP by orderNumber
SELECT total
FROM viewTotaleOrdini
WHERE orderNumber = 10102;
SHOW CREATE VIEW nomeVista;
DROP VIEW nomeVista;
ALTER VIEW nomeVista AS nuovaSELECT;
Posso modificare i dati di una vista se la SELECT:
CREATE VIEW officeInfo
AS SELECT officeCode, phone, city
FROM offices;
UPDATE officeInfo
SET phone = '+39 040 55558555'
WHERE officeCode = 4;
MySQL:
CREATE USER nome@host
IDENTIFIED BY 'password'
Oracle:
CREATE USER nome
IDENTIFIED BY password
SQL Server
CREATE USER nome
WITH PASSWORD = 'password'
'%'
per ogni host'nome@host'
crea un utente con username nome@host
legato all’host %
FLUSH PRIVILEGES
forza il reload dei datiCREATE USER pippo@localhost
IDENTIFIED BY 'pluto';
mysql
Tabella user
INSERT INTO user(host,user,password)
VALUES('localhost','pippo',
PASSWORD('pluto'));
FLUSH PRIVILEGES;
SET PASSWORD FOR user@host =
PASSWORD('Secret1970');
DROP USER user@host;
GRANT privilegio (colonne)
ON risorsa
TO account
[WITH GRANT OPTION]
privilegio
: tipo di operazione permessacolonne
: se si applica solo ad alcune colonnerisorsa
: database.tabella — wildcard: *account
: utente@hostWITH GRANT OPTION
: l’utente può propagare i permessi ad altriALL
: tuttiALTER
: modificare tabellaCREATE
: creare oggettiDELETE
: eliminare ennupleSELECT
: leggere i datiUPDATE
: modificare i datiHint: GRANT privilegio (colonne)
ON risorsa
TO account
GRANT SELECT, UPDATE, DELETE ON
classicmodels.* TO 'pippo'@'%';
GRANT ALL ON *.* TO 'super'@'localhost'
WITH GRANT OPTION;
GRANT SELECT (phone, customerName),
UPDATE (phone)
ON classicmodels.customers
TO 'someuser'@'somehost';
SHOW GRANTS FOR utente;
Sintassi molto simile a GRANT
REVOKE privilege_type [(column_list)]
[, priv_type [(column_list)]]...
ON [object_type] privilege_level
FROM user [, user]...
REVOKE UPDATE, DELETE ON
classicmodels.* FROM
'rfc'@'localhost';
Esempio: trasferimento di fondi da un conto A ad un conto B: o si fanno il prelevamento da A e il versamento su B o nessuno dei due
Esempio: se due assegni emessi sullo stesso conto corrente vengono incassati contemporaneamente si deve evitare di trascurarne uno
In MySQL:
START TRANSACTION
: specifica l’inizio della transazione (le operazioni non vengono eseguite sulla base di dati)COMMIT
: le operazioni specificate a partire dal begin transaction vengono eseguiteROLLBACK
: si rinuncia all’esecuzione delle operazioni specificate dopo l’ultimo begin transactionSQL Server
BEGIN TRANSACTION
COMMIT WORK
ROLLBACK WORK
start transaction;
select @orderNumber := max(orderNUmber) from orders;
set @orderNumber = @orderNumber + 1;
insert into orders(orderNumber, orderDate, requiredDate, shippedDate, status, customerNumber)
values(@orderNumber, now(), date_add(now(), INTERVAL 5 DAY),
date_add(now(), INTERVAL 2 DAY), 'In Process', 145);
insert into orderdetails(orderNumber, productCode, quantityOrdered, priceEach, orderLineNumber)
values(@orderNumber,'S18_1749', 30, '136', 1),
(@orderNumber,'S18_2248', 50, '55.09', 2);
commit;
Qualcosa è sempre in memoria e può sempre essere perso