Introduzione a SQL mediante esempi

Con SQL è possibile creare database ma anche interrogare dati sulla base di database esistenti. Il linguaggio appartiene al repertorio standard dello sviluppo web, analisi dati e ricerca. Rispetto ad altri linguaggi di programmazione, SQL è speciale: in questo articolo vi mostriamo com’è strutturato e come funziona.

Registrazione dominio

Più di un semplice nome.

Registra il tuo dominio con IONOS e approfitta di tutte le nostre funzionalità.

E-Mail
SSL Wildcard
Supporto 24/7

Che cos’è SQL?

SQL è l’acronimo di “Structured Query Language”, in italiano “linguaggio di interrogazione strutturato”. Nato a metà degli anni ‘70, SQL è diventato il linguaggio di programmazione standard per le applicazioni database. In questo senso SQL va ben oltre le query che gli danno il nome: il linguaggio rappresenta l’interfaccia pioniera per l’interazione con i dati relazionali, ovvero i sistemi di gestione dei database relazionali.

Per capire com’è fatto SQL è essenziale sapere che il linguaggio è basato sull’“algebra relazionale”. Si tratta di una teoria matematica per strutturare dati e calcolare i risultati delle query. Da queste fondamenta matematiche derivano molte delle caratteristiche di SQL come linguaggio di programmazione.

SQL come interfaccia per il controllo di RDBMS

SQL funziona come interfaccia per la comunicazione con un sistema di gestione di database relazionale (RDBMS). Il codice SQL viene immesso ed eseguito direttamente da persone mediante un’interfaccia di testo oppure viene integrato in accessi API. Inoltre, esistono interfacce grafiche che traducono le interazioni degli utenti in codice SQL. In ogni caso il codice SQL viene eseguito da un RDBMS, il quale è composto da vari componenti:

  1. Engine di memoria o database: gestisce dati dal punto di vista tecnico.
  2. Interfacce di programmazione API: consentono il controllo programmatico del RDBMS e offrono accesso ai dati.
  3. Interfacce utente (GUI/CLI): permettono il controllo del RDBMS e l’accesso a dati tramite esseri umani.
  4. Database veri e propri: organizzano dati dal punto di vista logico.

Un RDBMS comprende una gerarchia di livelli di memoria, dal server database fino al valore memorizzato in un campo. SQL si serve di comandi per operare su ciascuno di essi. Vi mostriamo la gerarchia degli oggetti RDBMS in una tabella riepilogativa:

Oggetto RDBMS Contiene
Server Database
Database Tabelle
Tabelle Record
Record Campi
Campo Valore tipizzato

SQL è un linguaggio dichiarativo e specifico per domini

In confronto alla maggior parte dei linguaggi affermati, SQL è speciale. Primo perché è nato prima dell’epoca di Internet, inoltre perché si tratta di un “linguaggio specifico per domini” (“Domain-Specific Language”, DSL). Al suo opposto si parla di “General Purpose Languages” (GLS), linguaggi adatti a una serie di scenari diversi. Rappresentanti noti dei General Purpose Languages sono C, C++, C#, Java, JavaScript, Python e PHP.

Tra i linguaggi utilizzati nel web moderno, anche il CSS è un linguaggio specifico per domini. È interessante notare che sia per SQL che per CSS si tratta di linguaggi di programmazione “dichiarativi”. Vale a dire che chi programma descrive un risultato e il sistema che esegue il codice si occupa di ottenere il risultato. Ciò si contrappone alla diffusa programmazione “imperativa”, nella quale i singoli passaggi per raggiungere l’obiettivo sono stabiliti esplicitamente nel codice.

La portata linguistica di SQL è determinata da diversi standard ISO/IEC. A prescindere da ciò, esistono dialetti delle differenti implementazioni SQL dei grandi provider. Pertanto MySQL/MariaDB, PostgreSQL, Oracle SQL e Microsoft SQL Server sono dotati di comandi e varianti di comandi propri.

Quando viene applicato SQL?

Con SQL è possibile controllare tutti gli aspetti di un RDBMS. Anche se in generale SQL è considerato come un linguaggio, la sua funzionalità si estende oltre un minimo di cinque sottolinguaggi definiti. Ognuno dei cinque linguaggi comprende comandi SQL propri che coprono il rispettivo ambito parziale. Vediamo alcuni esempi:

Sottolinguaggi SQL Comandi Esempi
Data Definition Language (DDL) Comandi per la definizione dello schema del database: per creare, modificare ed eliminare tabelle di database; definizione di chiavi primarie, chiavi estranee e constraint CREATE TABLE, DROP TABLE
Data Manipulation Language (DML) Comandi per la manipolazione di dati: per modificare, aggiungere ed eliminare record INSERT, UPDATE
Data Query Language (DQL) Comandi per l’interrogazione e preparazione di dati SELECT
Data Control Language (DCL) Comandi per la gestione dei permessi GRANT, REVOKE
Transaction Control Language (TCL) Comandi per il controllo di transazione COMMIT, ROLLBACK

Imparare la sintassi SQL sulla base di esempi

In generale con sintassi si intende la “scrittura” di un linguaggio di programmazione. La sintassi determina quali tipi di costrutti di codice fondamentali esistono e come collegarli tra loro. Capire la sintassi è un presupposto imprescindibile per la lettura e la scrittura del codice nel relativo linguaggio. Prima di affrontare la sintassi SQL nel dettaglio, osserviamo come viene eseguito il codice SQL.

Consiglio

Imparate a utilizzare MySQL in modo facile grazie al nostro tutorial MySQL.

Come si esegue il codice SQL?

Il codice SQL si trova in file di testo sotto forma di codice sorgente e prende vita solo tramite un ambiente di esecuzione adatto. Il codice sorgente viene letto da un interprete SQL e tradotto in azioni di un RDBMS. Per farlo esistono due approcci di base:

  1. Esecuzione del codice SQL in una sessione interattiva

Questo approccio prevede che il codice SQL venga direttamente immesso o copiato in una finestra di testo. Il codice SQL viene eseguito e viene mostrato il risultato. Si ha ora la possibilità di adattare il codice ed eseguirlo nuovamente. Grazie a una veloce successione di manipolazione del codice e visualizzazione dei risultati, questo approccio è particolarmente adatto per l’apprendimento e la realizzazione di richieste complesse.

  1. Esecuzione del codice SQL come script

In questo approccio un intero file di codice sorgente viene eseguito riga per riga. L’utente riceve un feedback solo alla fine dell’esecuzione. Questa procedura è l’ideale per automatizzare processi e importare backup di database MySQL con MySQL dump.

Interfaccia Spiegazione Esempi
Interfaccia a riga di comando (CLI) Interfaccia basata su testo; il codice SQL viene inserito ed eseguito, il risultato mostrato come testo mysql, psql, mysqlsh
Interfaccia grafica (GUI) Il codice SQL viene inserito nella finestra di testo e/o generato come reazione a un’interazione utente; il codice SQL viene eseguito, il risultato espresso in tabelle phpMyAdmin, MySQL Workbench, HeidiSQL
Interfaccia di programmazione (API) Permette la comunicazione diretta con un RDBMS; il codice SQL viene incluso ed eseguito come stringa nel rispettivo linguaggio di programmazione; i risultati sono a disposizione per un ulteriore utilizzo come strutture di dati PHP Data Objects (PDO), Connector/J (Java), Connector/Python, C API

Costrutti di sintassi in SQL

I costrutti di sintassi più importanti in SQL sono applicazioni SQL con eventuali clausole al loro interno. Nonostante tecnicamente la definizione non sia del tutto corretta, in generale entrambe sono conosciute come “comandi SQL”. In aggiunta, esistono altri costrutti sintattici che illustriamo nella seguente tabella:

Termine Corrispondente inglese Spiegazione Esempio
Istruzione Statement Il DBMS impartisce l’istruzione di eseguire un’azione; termina con un punto e virgola CREATE TABLE People;
Clausola Clause Modifica un’istruzione; possono presentarsi solo all’interno di istruzioni WHERE, HAVING
Espressione Espressione Restituisce un valore durante la valutazione 6 * 7
Identificatore Identifier Nome di un oggetto database, di una variabile o di una procedura; può essere qualificato o meno dbname.tablename / tablename
Predicato Predicate Termine che valuta TRUE, FALSE o UNKNOWN Age < 42
Interrogazione Query Istruzione specifica; restituisce l’insieme di risultati dei record SELECT Name FROM People WHERE Age < 42;
Funzione Function Elabora uno o più valori, generalmente creando un nuovo valore UPPER('text') -- Restituisce 'TEXT'
Commento Comment Serve a commentare il codice SQL; viene ignorato da RDBMS -- Commento fino alla fine della riga / /* Eventuale commento su più righe */
N.B

Di solito i comandi SQL come SELECT e CREATE TABLE sono scritti in maiuscolo. Tuttavia, nella pratica SQL non fa alcuna distinzione tra caratteri maiuscoli e minuscoli, pertanto si tratta esclusivamente di una convenzione ampiamente diffusa.

Costruire una gestione di prodotto con SQL a titolo di esempio

Il modo migliore per imparare un linguaggio di programmazione è usarlo. Di seguito creeremo un mini database e lo consulteremo con delle query. Per farlo ci serviremo di Online SQL interpreter del sito web sql.js. Aprite il sito web nel link e sostituite il codice inserito SQL con quello dei nostri esempi. Per visualizzare i risultati eseguite il codice pezzo per pezzo.

Approccio di base per la costruzione di un database SQL

A titolo di esempio costruiremo una gestione di prodotto commerciale, la stessa che servirebbe per un negozio fisico o uno online. Stabiliamo velocemente qualche criterio:

  • Esiste una serie di prodotti e disponiamo di una determinata quantità di ciascuno di essi in magazzino.
  • La clientela fissa è composta da una moltitudine di persone.
  • Una cliente o un cliente effettua un ordine che può contenere più articoli.
  • Per ciascun ordine salviamo la data e la persona che l’ha creato così come il tipo e la quantità di articoli.

Innanzitutto traduciamo questi obiettivi in una descrizione astratta e infine in codice SQL rispettando il seguente schema:

  1. Creare un modello
  2. Definire lo schema
  3. Inserire record
  4. Definire query

Creare un modello delle entità e delle relazioni

Il primo passaggio avviene sulla carta, ovvero si serve di strumenti di modellazione speciali. Raccogliamo informazioni sul sistema da modellare e ne astraiamo entità e relazioni. Spesso questo passaggio si concretizza in termini di Entity Relationship (ER) Diagram.

Quali entità esistono e come sono collegate tra loro? Le entità sono classi di cose. Nel nostro esempio della gestione dei prodotti si trovano le entità prodotto, cliente e ordine. Per ciascuna entità occorre una tabella. A causa delle peculiarità del modello relazionale si aggiungono ulteriori tabelle per modellare le relazioni. Per riconoscerlo e applicarlo correttamente è necessaria una certa esperienza.

La domanda centrale è come sono interconnesse le entità considerando entrambe le direzioni di una relazione e differenziando tra singolare e plurale. Ad esempio nella relazione persona–automobile:

  1. “A una persona appartengono potenzialmente diverse automobili”
  2. “Un’automobile appartiene solo a una persona”

Da due entità nascono tre possibili scenari relazionali:

Relazione Entità Da sinistra Da destra
Relazione 1:1 Automobile:targa “Un’automobile dispone esattamente di una targa” “Una targa appartiene solo a un’automobile”
Relazione 1:n Persona:automobile “A una persona possono potenzialmente appartenere diverse automobili” “Un’automobile appartiene solo a una persona”
Relazione m:n Automobile:strada “Un’automobile viaggia su più strade” “Su una strada viaggiano più automobili”

Implementare i prodotti

Innanzitutto implementiamo la tabella dei prodotti. Per farlo, definiamo uno schema, inseriamo i record ed eseguiamo un paio di query di prova. A seguire approfondiamo i singoli passaggi.

Definire lo schema

Il comando SQL centrale per definire le tabelle di database è CREATE TABLE. Il comando genera una tabella con nome e stabilisce proprietà per le colonne. Allo stesso modo vengono definiti tipi di dati ed eventualmente limitazioni per i valori da salvare:

DROP TABLE IF EXISTS Products;
CREATE TABLE Products ( product_id int, product_name text, stocked int, price int );
N.B.

Prima della definizione delle tabelle utilizziamo un’istruzione DROP TABLE IF EXISTS. Questa rimuove eventuali tabelle esistenti e permette di eseguire il medesimo codice SQL più volte senza provocare messaggi di errore.

Inserire record

Creiamo un paio di record di prova. Per farlo ci serviamo del comando SQL INSERT INTO e della funzione VALUES per riempire i campi:

INSERT INTO Products VALUES (10, 'ABC Product', 74, 1050);
INSERT INTO Products VALUES (20, 'KLM Product', 23, 750);
INSERT INTO Products VALUES (30, 'XYZ Product', 104, 350);

Definire le query

Per verificare lo stato della tabella dei prodotti formuliamo una semplice interrogazione. Adoperiamo il comando SELECT FROM ed emettiamo l’intera tabella:

SELECT * FROM Products;

In aggiunta compiliamo una query un po’ più complessa, che calcola il valore complessivo dei prodotti in magazzino:

SELECT product_name AS 'Name', (stocked * price) AS 'Value' FROM Products;

Implementare le altre tabelle

Nel corso della procedura ci occupiamo delle restanti tabelle necessarie seguendo il medesimo approccio della tabella di prodotti. Prima creiamo una tabella clienti:

DROP TABLE IF EXISTS Customers;
CREATE TABLE Customers ( customer_id int, customer_name text, contact text );

Vi inseriamo record per due esempi di clienti:

INSERT INTO Customers VALUES (100, 'EDC Customer', 'ED@example.com');
INSERT INTO Customers VALUES (200, 'WVU Customer', 'WV@example.com');

Verifichiamo emettendo la tabella clienti:

SELECT * FROM Customers;

Successivamente, formiamo la tabella ordini:

DROP TABLE IF EXISTS Orders;
CREATE TABLE Orders ( order_id int, customer_id int, order_date text );

Inseriamo ora tre esempi di ordine. Osservate come al primo valore del record abbiamo assegnato un ID come chiave primaria. Per quanto riguarda il secondo valore, invece, si tratta di un ID cliente già esistente come chiave estranea. A questo punto salviamo la data dell’ordine:

INSERT INTO Orders VALUES (1000, 100, '2022-05-03');
INSERT INTO Orders VALUES (1001, 100, '2022-05-04');
INSERT INTO Orders VALUES (1002, 200, '2022-05-08');

Per testare emettiamo l’ordine:

SELECT * FROM Orders;

Infine, ci serve una tabella per i prodotti contenuti in un ordine, inclusa la quantità. Si tratta di una relazione m:n, poiché un ordine può contenere più articoli e un articolo può essere presente in più ordini. Definiamo la tabella contenente gli ID degli ordini e dei prodotti come chiavi estranee:

DROP TABLE IF EXISTS OrderItems;
CREATE TABLE OrderItems ( orderitem_id int, order_id int, product_id int, count int );

Inseriamo un paio di prodotti ordinati scegliendo gli ID degli ordini e dei prodotti in modo tale che risulti un ordine con due prodotti e un altro ordine con un solo prodotto:

INSERT INTO OrderItems VALUES (10001, 1000, 10, 3);
INSERT INTO OrderItems VALUES (10002, 1000, 20, 2);
INSERT INTO OrderItems VALUES (10003, 1002, 30, 12);

Verifichiamo emettendo i prodotti ordinati:

SELECT * FROM OrderItems;

Formulare query complesse

Una volta eseguite le stringhe di codice mostrate, dovreste riuscire a capire la struttura del nostro database di prova. Passiamo ora a interrogazioni più complesse che mettono in evidenza la potenza di SQL. Per prima cosa formuliamo una query che riunisce dati diffusi su più tabelle. Utilizziamo il comando SQL JOIN per collegare i dati della tabella clienti e quelli della tabella ordini. Diamo un nome ad alcune colonne e stabiliamo una corrispondenza degli ID clienti come condizione JOIN. Tenete presente che ci serviamo di identificatori qualificati per distinguere tra le due tabelle:

SELECT customers.customer_name as 'Customer', customers.customer_id, orders.order_id, orders.order_date AS 'Date' FROM Customers JOIN Orders ON Orders.customer_id = Customers.customer_id ORDER BY Customers.customer_id;

Per concludere, utilizziamo un ulteriore comando JOIN per calcolare i costi totali dei prodotti ordinati:

SELECT OrderItems.order_id, OrderItems.orderitem_id AS 'Order Item', Products.product_name AS 'Product', Products.price AS 'Unit Price', OrderItems.count AS 'Count', (OrderItems.count * Products.price) AS 'Total' FROM OrderItems JOIN Products ON OrderItems.product_id = Products.product_id;

Quali sono i vantaggi e gli svantaggi di SQL?

Vantaggi di SQL

I maggiori vantaggi di SQL sono la sua elevata popolarità e l’ampia diffusione della tecnologia. Nell’ambito delle soluzioni database, infatti, rappresenta uno standard del settore. Pertanto permette di trovare facilmente persone esperte di SQL. In più, a fronte di permessi assegnati correttamente è possibile garantire un accesso al sistema a chi fa analisi senza correre il rischio di causare errori.

L’approccio basato sull’algebra relazionale poggia su robuste fondamenta matematiche. Ciò consente una memorizzazione ottimale dei dati, richiedendo però una forte comprensione della tecnologia nonché abilità nella modellazione. A posteriori, in uno schema ben progettato è possibile ottenere nuove informazioni dai dati.

Svantaggio di SQL: elevata complessità del linguaggio

Un forte svantaggio di SQL è l’elevata complessità del linguaggio. Mentre un linguaggio di programmazione come Python se la cava con meno di 40 comandi, SQL comprende centinaia di comandi e clausole. A complicare ciò, si aggiunge il fatto che molti di essi sono specifici per l’implementazione.

La struttura di un database SQL necessita di una serie di supposizioni sui dati da salvare. Queste supposizioni vengono stabilite nello schema del database e idealmente garantiscono la qualità dei dati. Tuttavia, in caso di schema progettato male, si dovrà continuamente avere a che fare con problemi e complicazioni, poiché modificare lo schema sul sistema in corso d’opera rappresenta una vera e propria sfida.

L’ottimizzazione della performance di un database SQL con molti accessi o grandi quantità di dati è tutt’altro che semplice. Una distribuzione geografica risulta estremamente impegnativa e richiede persone esperte e approcci sofisticati quali partizionamento e sharding.

Svantaggio di SQL: disadattamento di impedenza

La programmazione orientata agli oggetti (OOP) è ampiamente diffusa. Tutti i linguaggi OOP condividono il fatto che i dati sono presenti come oggetti incapsulati. In genere un programma OOP comprende sistemi di oggetti interconnessi. Oltre ai dati, gli oggetti comprendono un “atteggiamento” sotto forma di propri metodi, ereditati mediante gerarchie di classi.

Per contro, l’approccio relazionale è sostanzialmente diverso: i dati sono distribuiti su più tabelle e non è possibile modellare il comportamento degli oggetti. Invece, entrano in azione query e constraint dei campi. Le peculiarità di OOP non sono trasferibili 1:1 alle strutture di database relazionali. Con riferimento a un fenomeno dell’ingegneria elettronica, si parla di “disadattamento di impedenza”.

Per colmare il divario tra OOP e RDBMS basati su SQL, si ricorre alle cosiddette mappature relazionali a oggetti (object-relational mapping, ORM). L’ORM è un livello di traduzione che istanzia gli oggetti secondo le necessità e trasmette loro i dati dal database o li scrive dagli oggetti nel database.

Quali sono le possibili alternative a SQL?

Da decenni i sistemi di gestione di database relazionali (RDBMS), e quindi SQL, rappresentano la tecnologia database predominante. Al giorno d’oggi esistono molteplici alternative con vari gradi di sovrapposizione con gli RDBMS SQL. Prendiamo in esame tre alternative diffuse:

PostgreSQL

PostgreSQL è un potente sistema di gestione di database relazionali a oggetti (ORDBMS). Oltre a SQL come linguaggio di interrogazione, supporta direttamente i concetti fondamentali della programmazione orientata agli oggetti. Le gerarchie di oggetti, l’ereditarietà e il comportamento degli oggetti sono utilizzabili anche senza ricorrere alla mappatura relazionale a oggetti (ORM). Nella fattispecie, i tipi di dati definiti dall’utente e quelli compositi limitano la complessità di schemi e query.

SQLite

SQLite è un database SQL incorporato disponibile con licenza open source. Questo database SQL ridotto è integrato come libreria e funziona direttamente su browser e dispositivi mobili. Si distingue per la bassa complessità del sistema: l’intero database è disponibile in un unico file binario.

NoSQL

Il termine NoSQL rimanda a una famiglia di DBMS non relazionali. Anziché modellare i dati principalmente come campi di tabelle, vengono adottati approcci diversi. Di norma, le soluzioni NoSQL sono meno complesse e offrono vantaggi dal punto di vista della scalabilità e dell’ottimizzazione delle prestazioni. Peraltro, solitamente è più facile modificare lo schema in corso d’opera e memorizzare i dati in modo flessibile. In compenso, potrebbero esserci meno garanzie sulla qualità dei dati.

Tra le soluzioni NoSQL più diffuse si ricordano:

Per offrirti una migliore esperienza di navigazione online questo sito web usa dei cookie, propri e di terze parti. Continuando a navigare sul sito acconsenti all’utilizzo dei cookie. Scopri di più sull’uso dei cookie e sulla possibilità di modificarne le impostazioni o negare il consenso.