Gestire i Valori NULL nei Database: Guida Completa a COALESCE e IFNULL in SQL

Principiante
Database e SQL

Scopri come COALESCE e IFNULL ti aiutano a gestire i valori NULL nei tuoi database SQL. Questa guida per principianti esplora le differenze, gli usi e gli esempi pratici di queste funzioni essenziali per una programmazione web robusta.

Pubblicato
Tag
programmazione web Beginner database sql Query COALESCE IFNULL NULL Dati

La gestione dei dati è il cuore di ogni applicazione web. Che tu stia costruendo un e-commerce, un social network o un semplice blog, i dati sono la risorsa più preziosa. Tuttavia, non tutti i dati sono sempre completi o presenti. Spesso ci imbattiamo in quello che nel mondo dei database viene chiamato un valore NULL.

Capire e gestire correttamente i NULL è fondamentale per evitare errori, migliorare la leggibilità dei report e garantire che la tua applicazione si comporti come previsto. Immagina di dover calcolare la media dei voti degli studenti, ma alcuni studenti non hanno ancora sostenuto l'esame per una materia specifica. Se questi campi contengono NULL, un calcolo diretto potrebbe produrre risultati inaspettati o addirittura errori.

In questa guida completa, esploreremo due funzioni SQL potentissime e ampiamente utilizzate per affrontare il problema dei NULL: IFNULL e COALESCE. Vedremo cosa sono, come funzionano, quando usarle e le loro differenze, fornendo esempi pratici che potrai applicare subito nei tuoi progetti di programmazione web.

Comprendere i Valori NULL: Cosa Sono e Perché Contano

Prima di addentrarci nelle soluzioni, è cruciale capire esattamente cosa sia un valore NULL in un database relazionale e perché la sua gestione è così importante.

Cos'è un Valore NULL?

In SQL, NULL non è uno zero, non è una stringa vuota (''), e non è false. NULL rappresenta l'assenza di un valore. Indica che un dato è sconosciuto, non applicabile o semplicemente non è stato fornito. È un concetto unico e distinto da qualsiasi altro valore.

Considera una tabella Utenti con colonne come nome, email e telefono. Se un utente si registra e fornisce solo nome ed email, il campo telefono potrebbe essere lasciato NULL. Questo significa che non abbiamo un numero di telefono per quell'utente, non che il suo numero è '0' o una stringa vuota.

Perché i NULL sono un Problema?

I valori NULL possono creare diverse complicazioni se non gestiti correttamente:

  1. Calcoli Matematici: La maggior parte delle funzioni aggregate (come SUM(), AVG(), COUNT()) ignora i valori NULL per impostazione predefinita. Questo può portare a risultati inaspettati. Ad esempio, AVG(colonna) calcolerà la media solo sui valori non NULL, che potrebbe non essere ciò che desideri se intendevi includere tutti gli elementi, anche quelli con valore mancante (magari trattandoli come 0).
  2. Visualizzazione dei Dati: Quando i dati vengono visualizzati in un'interfaccia utente, un campo NULL potrebbe apparire come uno spazio vuoto, null testuale o un errore, rendendo l'interfaccia meno user-friendly o confusa per l'utente finale.
  3. Logica Condizionale: I confronti con NULL si comportano in modo speciale. NULL = NULL restituisce UNKNOWN, non TRUE o FALSE. Questo significa che WHERE colonna = NULL non funzionerà come previsto; dovrai usare WHERE colonna IS NULL o WHERE colonna IS NOT NULL.
  4. Integrità dei Dati: Se un campo dovrebbe sempre avere un valore, ma per errore contiene NULL, l'integrità dei dati è compromessa. Le colonne possono essere dichiarate NOT NULL per prevenire questo, ma non sempre è possibile o desiderabile per tutti i campi.

Ecco un esempio di una tabella Prodotti con alcuni valori NULL:

CREATE TABLE Prodotti (
    id INT PRIMARY KEY AUTO_INCREMENT,
    nome VARCHAR(100) NOT NULL,
    prezzo DECIMAL(10, 2) NOT NULL,
    sconto DECIMAL(5, 2) DEFAULT NULL,
    data_scadenza DATE DEFAULT NULL
);

INSERT INTO Prodotti (nome, prezzo, sconto, data_scadenza) VALUES
('Laptop', 1200.00, 0.10, '2024-12-31'),
('Mouse', 25.00, NULL, NULL),
('Tastiera', 75.00, 0.05, '2025-06-15'),
('Monitor', 300.00, NULL, '2024-10-01'),
('Webcam', 50.00, 0.00, NULL);

SELECT * FROM Prodotti;

Output:

id | nome     | prezzo   | sconto | data_scadenza
---|----------|----------|--------|---------------
1  | Laptop   | 1200.00  | 0.10   | 2024-12-31
2  | Mouse    | 25.00    | NULL   | NULL
3  | Tastiera | 75.00    | 0.05   | 2025-06-15
4  | Monitor  | 300.00   | NULL   | 2024-10-01
5  | Webcam   | 50.00    | 0.00   | NULL

Come puoi vedere, i campi sconto e data_scadenza contengono valori NULL per alcuni prodotti. Questo è il contesto in cui IFNULL e COALESCE diventano strumenti indispensabili.

IFNULL: La Funzione Semplice per MySQL (e Compatibili)

La funzione IFNULL è una soluzione diretta e facile da usare per gestire i valori NULL, particolarmente popolare in MySQL e nei database compatibili come MariaDB.

Sintassi e Spiegazione

La sintassi di IFNULL è molto semplice:

IFNULL(espressione, valore_sostitutivo)

Dove:

  • espressione: È l'espressione (solitamente una colonna) che vuoi controllare per i valori NULL.
  • valore_sostitutivo: È il valore che verrà restituito se espressione è NULL.

In pratica, IFNULL valuta il primo argomento. Se il primo argomento non è NULL, IFNULL restituisce quel valore. Se il primo argomento è NULL, allora restituisce il secondo argomento, ovvero il valore_sostitutivo.

Esempi Pratici con IFNULL

Riprendiamo la nostra tabella Prodotti. Vogliamo mostrare lo sconto applicato, ma se un prodotto non ha sconto (ovvero sconto è NULL), vogliamo visualizzare 0.00 invece di NULL.

SELECT
    nome,
    prezzo,
    IFNULL(sconto, 0.00) AS sconto_visualizzato,
    prezzo * (1 - IFNULL(sconto, 0.00)) AS prezzo_finale
FROM Prodotti;

Spiegazione:

  • Per i prodotti 'Laptop', 'Tastiera' e 'Webcam', sconto ha un valore (0.10, 0.05, 0.00), quindi IFNULL restituisce quel valore. Il prezzo_finale viene calcolato correttamente.
  • Per 'Mouse' e 'Monitor', sconto è NULL. IFNULL(sconto, 0.00) sostituisce NULL con 0.00. Di conseguenza, il prezzo_finale per questi prodotti sarà uguale al prezzo originale, dato che lo sconto è 0.

Output:

nome     | prezzo   | sconto_visualizzato | prezzo_finale
---------|----------|---------------------|---------------
Laptop   | 1200.00  | 0.10                | 1080.00
Mouse    | 25.00    | 0.00                | 25.00
Tastiera | 75.00    | 0.05                | 71.25
Monitor  | 300.00   | 0.00                | 300.00
Webcam   | 50.00    | 0.00                | 50.00

Un altro esempio: se la data_scadenza è NULL, vogliamo mostrare una stringa come 'Non specificata'.

SELECT
    nome,
    IFNULL(data_scadenza, 'Non specificata') AS scadenza_prodotto
FROM Prodotti;

Output:

nome     | scadenza_prodotto
---------|-------------------
Laptop   | 2024-12-31
Mouse    | Non specificata
Tastiera | 2025-06-15
Monitor  | 2024-10-01
Webcam   | Non specificata

Limitazioni di IFNULL

La principale limitazione di IFNULL è che è specifica per MySQL (e MariaDB). Non è uno standard SQL ANSI e potrebbe non funzionare in altri sistemi di gestione di database (DBMS) come PostgreSQL, SQL Server o Oracle. Inoltre, può gestire solo due argomenti: l'espressione da controllare e il valore di sostituzione. Se hai bisogno di una logica più complessa o di verificare più colonne in sequenza, IFNULL non è sufficiente.

COALESCE: La Funzione Universale e Potente

La funzione COALESCE è la risposta standard SQL per la gestione dei NULL. È più flessibile e portatile di IFNULL, rendendola una scelta eccellente per progetti che potrebbero dover funzionare su diversi DBMS o che richiedono una logica di fallback più complessa.

Sintassi e Spiegazione

La sintassi di COALESCE è la seguente:

COALESCE(espressione1, espressione2, ..., espressioneN)

Dove espressione1, espressione2, ..., espressioneN sono una lista di espressioni. COALESCE valuta le espressioni nell'ordine in cui sono elencate e restituisce il valore della prima espressione che non è NULL. Se tutte le espressioni sono NULL, allora COALESCE restituisce NULL.

Questo la rende incredibilmente potente, poiché puoi fornire una serie di opzioni di fallback. Immagina di voler visualizzare un indirizzo e-mail: se l'e-mail principale non è disponibile, prova quella secondaria, e se anche quella è assente, usa un'e-mail di contatto generica.

Come Funziona l'Ordine di Valutazione

L'ordine è cruciale. COALESCE si ferma alla prima espressione non NULL che incontra. Questo significa che se espressione1 non è NULL, le espressione2 e successive non verranno nemmeno valutate. Questo può avere implicazioni sulle performance se alcune espressioni sono costose da calcolare, ma in genere per semplici colonne non è un problema significativo.

Esempi Pratici con COALESCE

Useremo ancora la nostra tabella Prodotti e poi ne creeremo una nuova per mostrare la potenza di COALESCE con più argomenti.

Esempio con due argomenti (simile a IFNULL)

SELECT
    nome,
    prezzo,
    COALESCE(sconto, 0.00) AS sconto_visualizzato,
    prezzo * (1 - COALESCE(sconto, 0.00)) AS prezzo_finale
FROM Prodotti;

Come puoi vedere, l'output è identico a quello ottenuto con IFNULL. Questo dimostra che COALESCE con due argomenti è funzionalmente equivalente a IFNULL.

Output:

nome     | prezzo   | sconto_visualizzato | prezzo_finale
---------|----------|---------------------|---------------
Laptop   | 1200.00  | 0.10                | 1080.00
Mouse    | 25.00    | 0.00                | 25.00
Tastiera | 75.00    | 0.05                | 71.25
Monitor  | 300.00   | 0.00                | 300.00
Webcam   | 50.00    | 0.00                | 50.00

Esempio con più argomenti (la vera forza di COALESCE)

Supponiamo di avere una tabella Contatti con diverse opzioni per il contatto telefonico:

CREATE TABLE Contatti (
    id INT PRIMARY KEY AUTO_INCREMENT,
    nome VARCHAR(100) NOT NULL,
    telefono_principale VARCHAR(20) DEFAULT NULL,
    telefono_ufficio VARCHAR(20) DEFAULT NULL,
    telefono_cellulare VARCHAR(20) DEFAULT NULL
);

INSERT INTO Contatti (nome, telefono_principale, telefono_ufficio, telefono_cellulare) VALUES
('Alice', '111-222-3333', NULL, NULL),
('Bob', NULL, '444-555-6666', NULL),
('Charlie', NULL, NULL, '777-888-9999'),
('David', '100-200-3000', '101-202-3030', '102-203-3040'),
('Eve', NULL, NULL, NULL);

SELECT * FROM Contatti;

Output:

id | nome    | telefono_principale | telefono_ufficio | telefono_cellulare
---|---------|---------------------|------------------|-------------------
1  | Alice   | 111-222-3333        | NULL             | NULL
2  | Bob     | NULL                | 444-555-6666     | NULL
3  | Charlie | NULL                | NULL             | 777-888-9999
4  | David   | 100-200-3000        | 101-202-3030     | 102-203-3040
5  | Eve     | NULL                | NULL             | NULL

Ora vogliamo selezionare il miglior numero di telefono disponibile per ogni contatto, con una priorità: prima telefono_principale, poi telefono_ufficio, poi telefono_cellulare. Se nessuno è disponibile, vogliamo mostrare 'Nessun numero'.

SELECT
    nome,
    COALESCE(telefono_principale, telefono_ufficio, telefono_cellulare, 'Nessun numero') AS numero_contatto
FROM Contatti;

Spiegazione:

  • Alice: telefono_principale non è NULL, quindi viene restituito '111-222-3333'.
  • Bob: telefono_principale è NULL, quindi COALESCE passa a telefono_ufficio, che non è NULL, e restituisce '444-555-6666'.
  • Charlie: telefono_principale e telefono_ufficio sono NULL, quindi COALESCE passa a telefono_cellulare, che non è NULL, e restituisce '777-888-9999'.
  • David: telefono_principale non è NULL, quindi viene restituito '100-200-3000' (le altre colonne non vengono nemmeno considerate).
  • Eve: Tutti i campi telefono sono NULL, quindi COALESCE restituisce l'ultimo argomento, 'Nessun numero'.

Output:

nome    | numero_contatto
--------|-----------------
Alice   | 111-222-3333
Bob     | 444-555-6666
Charlie | 777-888-9999
David   | 100-200-3000
Eve     | Nessun numero

Compatibilità tra Diversi DBMS

Uno dei maggiori vantaggi di COALESCE è la sua portabilità. È una funzione standard SQL e quindi supportata dalla stragrande maggioranza dei sistemi di gestione di database relazionali, inclusi MySQL, PostgreSQL, SQL Server, Oracle, SQLite e molti altri. Questo la rende la scelta preferita per gli sviluppatori che mirano a creare applicazioni il più agnostiche possibile rispetto al database sottostante.

COALESCE vs. IFNULL: Quando Usare Cosa

Ora che abbiamo esplorato entrambe le funzioni, facciamo un confronto diretto per capire quando è opportuno usare l'una o l'altra.

Caratteristica IFNULL COALESCE
Sintassi IFNULL(expr1, expr2) COALESCE(expr1, expr2, ..., exprN)
Numero di Argomenti Esattamente 2 2 o più
Standard SQL No (specifica MySQL/MariaDB) Sì (standard ANSI SQL)
Portabilità Bassa (solo MySQL/MariaDB) Alta (supportata da quasi tutti i DBMS)
Logica di Fallback Semplice (un solo fallback) Complessa (sequenza di fallback multipli)
Tipo di Ritorno Tipo del primo argomento non NULL Tipo del primo argomento non NULL (o comune)

Scenari d'Uso Ideali

  • Usa IFNULL quando:

    • Stai lavorando esclusivamente con MySQL o MariaDB e non prevedi di cambiare DBMS in futuro.
    • Hai bisogno di una sostituzione semplice: se un valore è NULL, usa questo altro valore, altrimenti usa il valore originale.
    • La tua query è semplice e vuoi la massima leggibilità in un contesto MySQL.
  • Usa COALESCE quando:

    • La portabilità del tuo codice SQL è importante (es. se la tua applicazione deve supportare più DBMS o potresti migrare in futuro).
    • Hai bisogno di una logica di fallback più complessa, controllando più colonne o espressioni in sequenza fino a trovare il primo valore non NULL.
    • Stai lavorando con altri DBMS che non supportano IFNULL (come PostgreSQL, SQL Server, Oracle).

In generale, per la programmazione web moderna, soprattutto se si punta alla scalabilità e alla flessibilità, COALESCE è spesso la scelta più robusta e consigliata grazie alla sua standardizzazione e maggiore potenza.

Considerazioni sulla Performance

Per la maggior parte delle applicazioni e per dataset di dimensioni medie, la differenza di performance tra IFNULL e COALESCE è trascurabile. Entrambe le funzioni sono altamente ottimizzate dai motori di database. La scelta dovrebbe basarsi principalmente sulla portabilità e sulla complessità della logica di fallback necessaria, piuttosto che su micro-ottimizzazioni delle performance. Per dataset estremamente grandi o query molto complesse, è sempre consigliabile eseguire dei test di performance specifici per il proprio ambiente.

Esempi Pratici e Scenari d'Uso Reali

Vediamo alcuni scenari comuni nella programmazione web dove COALESCE e IFNULL si rivelano estremamente utili.

Scenario 1: Reportistica e Calcoli Aggregati

Immagina di dover generare un report sui guadagni totali, ma alcuni ordini potrebbero non avere un costo_spedizione registrato (quindi NULL). Se ignoriamo questi NULL nei calcoli, il totale potrebbe essere inferiore al reale. Vogliamo trattare NULL come 0 per i calcoli.

CREATE TABLE Ordini (
    id INT PRIMARY KEY AUTO_INCREMENT,
    prodotto VARCHAR(100) NOT NULL,
    prezzo_articolo DECIMAL(10, 2) NOT NULL,
    costo_spedizione DECIMAL(10, 2) DEFAULT NULL,
    data_ordine DATE
);

INSERT INTO Ordini (prodotto, prezzo_articolo, costo_spedizione, data_ordine) VALUES
('Maglietta', 25.00, 5.00, '2023-01-10'),
('Pantaloni', 50.00, NULL, '2023-01-12'),
('Scarpe', 80.00, 8.00, '2023-01-15'),
('Cappello', 15.00, NULL, '2023-01-18');

-- Calcolo del guadagno totale, trattando i costi di spedizione NULL come 0
SELECT
    SUM(prezzo_articolo + COALESCE(costo_spedizione, 0.00)) AS totale_guadagno_con_spedizione
FROM Ordini;

Spiegazione: COALESCE(costo_spedizione, 0.00) garantisce che anche gli ordini senza un costo di spedizione esplicito contribuiscano correttamente al totale, trattando il costo mancante come zero. Questo evita che il SUM() ignori completamente la riga o restituisca un risultato falsato.

Output:

totale_guadagno_con_spedizione
------------------------------
183.00

Scenario 2: Visualizzazione Dati Utente in un Profilo

Un utente può avere un'immagine del profilo, ma se non l'ha caricata, vogliamo mostrare un'immagine predefinita. Inoltre, se il nome utente non è impostato, vogliamo mostrare il nome completo, altrimenti 'Anonimo'.

CREATE TABLE Utenti (
    id INT PRIMARY KEY AUTO_INCREMENT,
    nome_utente VARCHAR(50) DEFAULT NULL,
    nome_completo VARCHAR(100) NOT NULL,
    url_immagine_profilo VARCHAR(255) DEFAULT NULL
);

INSERT INTO Utenti (nome_utente, nome_completo, url_immagine_profilo) VALUES
('john_doe', 'John Doe', 'http://example.com/john.jpg'),
(NULL, 'Jane Smith', 'http://example.com/jane_default.png'),
('guest_user', 'Guest User', NULL),
(NULL, 'Marco Rossi', NULL);

SELECT
    COALESCE(nome_utente, nome_completo, 'Anonimo') AS nome_visualizzato,
    COALESCE(url_immagine_profilo, 'http://example.com/default_avatar.png') AS avatar_url
FROM Utenti;

Spiegazione:

  • Per nome_visualizzato, COALESCE cerca prima nome_utente. Se è NULL, passa a nome_completo. Se anche quello è NULL, usa 'Anonimo'.
  • Per avatar_url, se url_immagine_profilo è NULL, viene usata l'immagine di default.

Output:

nome_visualizzato | avatar_url
------------------|-------------------------------------
john_doe          | http://example.com/john.jpg
Jane Smith        | http://example.com/jane_default.png
guest_user        | http://example.com/default_avatar.png
Marco Rossi       | http://example.com/default_avatar.png

Scenario 3: Gestione di Impostazioni o Preferenze

Un'applicazione potrebbe avere impostazioni a livello utente, ma se non specificate, dovrebbe usare impostazioni a livello di sistema. COALESCE è perfetta per questo.

CREATE TABLE ImpostazioniUtente (
    user_id INT PRIMARY KEY,
    tema VARCHAR(50) DEFAULT NULL,
    lingua VARCHAR(10) DEFAULT NULL
);

INSERT INTO ImpostazioniUtente (user_id, tema, lingua) VALUES
(1, 'dark', 'it'),
(2, NULL, 'en'),
(3, NULL, NULL);

-- Impostazioni di sistema predefinite
SET @default_tema = 'light';
SET @default_lingua = 'en';

SELECT
    iu.user_id,
    COALESCE(iu.tema, @default_tema) AS tema_applicato,
    COALESCE(iu.lingua, @default_lingua) AS lingua_applicata
FROM ImpostazioniUtente iu;

Spiegazione: COALESCE controlla l'impostazione dell'utente. Se è NULL, usa la variabile di sistema che contiene l'impostazione predefinita.

Output:

user_id | tema_applicato | lingua_applicata
--------|----------------|-----------------
1       | dark           | it
2       | light          | en
3       | light          | en

Questi esempi dimostrano come COALESCE e IFNULL possano semplificare la logica delle query, rendere i dati più gestibili e migliorare l'esperienza utente nelle applicazioni web.

Errori Comuni e Suggerimenti

Anche se COALESCE e IFNULL sono relativamente semplici, ci sono alcuni errori comuni e best practice da tenere a mente.

  1. Confondere NULL con '' o 0: Ricorda sempre che NULL è l'assenza di valore. '' è una stringa vuota, e 0 è un numero. Queste sono entità diverse. Se la tua colonna contiene stringhe vuote invece di NULL, COALESCE e IFNULL non interverranno, poiché '' non è NULL. Potresti aver bisogno di una combinazione con NULLIF (che trasforma un valore specifico in NULL) o un CASE statement per gestire anche le stringhe vuote.

    SELECT COALESCE('', 'Valore di default') AS risultato; -- Output: '' (stringa vuota, non NULL)
    SELECT COALESCE(NULLIF('', ''), 'Valore di default') AS risultato; -- Output: 'Valore di default'
    
  2. Incoerenza dei Tipi di Dato: Tutti gli argomenti passati a COALESCE (e a IFNULL) dovrebbero essere di un tipo di dato compatibile. Il database cercherà di determinare un tipo di dato comune per il risultato. Se passi tipi molto diversi (es. un numero e una data), potresti ottenere un errore o una conversione implicita indesiderata.

    -- Questo potrebbe dare un errore o un risultato inatteso a seconda del DBMS
    SELECT COALESCE(NULL, 123, 'testo') AS risultato;
    

    Generalmente, è meglio assicurarsi che il valore di fallback abbia lo stesso tipo di dato della colonna originale o un tipo facilmente convertibile.

  3. Non Testare a Sufficienza: Prima di implementare COALESCE o IFNULL in produzione, testa sempre le tue query con vari scenari di dati, inclusi casi in cui i valori sono NULL, non NULL, stringhe vuote, zeri, ecc., per assicurarti che il comportamento sia quello desiderato.

  4. Non Abusare: A volte, la presenza di NULL è il comportamento desiderato e non richiede alcuna sostituzione. Ad esempio, se stai calcolando una media e vuoi che solo i valori presenti contribuiscano, il comportamento predefinito delle funzioni aggregate (che ignorano NULL) è corretto. Usale solo quando hai una ragione specifica per sostituire i NULL.

Prossimi Passi per Approfondire

La gestione dei NULL è solo una parte dell'ampio mondo della manipolazione dei dati in SQL. Per continuare a migliorare le tue competenze nella programmazione web e nella gestione dei database, ti suggerisco di esplorare i seguenti argomenti:

  • NULLIF: Questa funzione è l'opposto di COALESCE/IFNULL. NULLIF(espressione1, espressione2) restituisce NULL se espressione1 è uguale a espressione2, altrimenti restituisce espressione1. È utile per trasformare valori specifici (come stringhe vuote o zeri) in NULL prima di usarli con COALESCE o altre funzioni.
  • CASE Statement: Per logiche condizionali più complesse che vanno oltre la semplice sostituzione di NULL, il CASE statement è lo strumento definitivo. Ti permette di definire regole personalizzate basate su condizioni multiple.
  • Gestione dei NULL a Livello di Applicazione: Oltre a gestirli nel database, è cruciale sapere come i linguaggi di programmazione (PHP, JavaScript con Node.js, Python, Java, ecc.) gestiscono i valori NULL o i loro equivalenti (null, None, undefined). Spesso, è necessario implementare controlli e fallback anche nel codice della tua applicazione per garantire robustezza e un'ottima esperienza utente.
  • Vincoli NOT NULL: Comprendi l'importanza di definire vincoli NOT NULL sulle colonne quando un valore è assolutamente essenziale. Questo impone l'integrità dei dati a livello di schema del database.
  • Normalizzazione del Database: Una buona progettazione del database può ridurre la necessità di valori NULL o gestirli in modo più strutturato. Studiare i principi della normalizzazione ti aiuterà a creare schemi di database più efficienti e robusti.

Dominare COALESCE e IFNULL è un passo significativo verso la scrittura di query SQL più professionali, leggibili e affidabili. Continua a praticare, a sperimentare con diversi scenari e a esplorare le altre potenti funzionalità che SQL offre per diventare un programmatore web ancora più competente.