Introduzione ai Tipi di Dato in MySQL
Benvenuti alla quarta lezione del nostro corso "Impara MySQL in 45 lezioni". Dopo aver compreso cos'è un database e come creare le prime tabelle, è fondamentale affrontare uno degli aspetti più critici della progettazione di un database: la scelta dei tipi di dato.
In MySQL, ogni colonna di una tabella deve avere un tipo di dato definito. Ma perché è così importante? Molti principianti tendono a usare tipi di dato generici (come TEXT per tutto o VARCHAR(255) per ogni stringa), pensando che ciò semplifichi il lavoro. In realtà, questa è una pratica errata che porta a tre problemi principali:
- Performance: I tipi di dato più specifici permettono a MySQL di indicizzare i dati in modo più efficiente e di eseguire le query più velocemente.
- Spazio di archiviazione: Un
INToccupa meno spazio di unVARCHARche contiene un numero. Su milioni di righe, questa differenza può tradursi in gigabyte di spazio risparmiato. - Integrità dei dati: Definendo un tipo
DATEper una data, impedisci che un utente inserisca accidentalmente una stringa come "Gennaio" dove dovrebbe esserci un formato standard YYYY-MM-DD.
In questa lezione esploreremo le categorie principali di tipi di dato: Numerici, Stringhe, Date e Tempo.
1. Tipi di Dato Numerici
I tipi numerici si dividono principalmente in numeri interi e numeri decimali. La scelta dipende dalla natura del dato che devi memorizzare.
Numeri Interi (Integers)
Gli interi sono utilizzati per contatori, ID (chiavi primarie) e quantità discrete. MySQL offre diverse varianti a seconda della dimensione del numero che prevedi di memorizzare:
- TINYINT: Molto piccolo. Ideale per valori booleani (0 o 1) o piccoli stati (es. status di un ordine).
- SMALLINT: Per numeri leggermente più grandi.
- MEDIUMINT: Una via di mezzo.
- INT: Il tipo più comune per gli ID delle tabelle.
- BIGINT: Fondamentale per applicazioni su scala globale (es. ID di post di un social network) dove il numero di record potrebbe superare i 2 miliardi.
Numeri Decimali e Virgola Mobile
Quando devi gestire prezzi, coordinate geografiche o misurazioni scientifiche, hai tre opzioni:
- DECIMAL(p, s): È il tipo "fisso".
prappresenta la precisione totale esle cifre decimali. Usa sempre DECIMAL per i soldi. Perché? Perché evita gli errori di arrotondamento tipici della virgola mobile. - FLOAT: Precisione singola. Utile per dati scientifici dove un piccolo errore di approssimazione non è crite.
- DOUBLE: Precisione doppia. Più accurato del FLOAT ma occupa più spazio.
Ecco un esempio di creazione di una tabella che utilizza diversi tipi numerici:
CREATE TABLE prodotti (
id INT AUTO_INCREMENT PRIMARY KEY, -- ID univoco per ogni prodotto
nome VARCHAR(100) NOT NULL,
prezzo DECIMAL(10, 2) NOT NULL, -- Massimo 10 cifre totali, 2 decimali (es. 99999999.99)
quantita_magazzino SMALLINT UNSIGNED, -- UNSIGNED impedisce valori negativi
valutazione_media FLOAT(3, 2) -- Esempio: 4.55
);
In questo codice, abbiamo usato DECIMAL per il prezzo per garantire che i calcoli finanziari siano esatti al centesimo. Abbiamo usato UNSIGNED per la quantità perché non può esistere un numero negativo di prodotti in magazzino.
2. Tipi di Dato per Stringhe
Le stringhe sono probabilmente i tipi di dato più utilizzati. La sfida qui è bilanciare la flessibilità con l'efficienza.
CHAR vs VARCHAR
Questa è la domanda classica per ogni principiante. Qual è la differenza?
- CHAR(n): È a lunghezza fissa. Se definisci
CHAR(5)e inserisci "Ciao" (4 caratteri), MySQL aggiungerà uno spazio vuoto per completare i 5. È più veloce per dati di lunghezza costante (es. codici fiscali, sigle di nazioni come 'IT', 'US'). - VARCHAR(n): È a lunghezza variabile. Se definisci
VARCHAR(255)ma inserisci "Ciao", MySQL occuperà solo lo spazio necessario per quei 4 caratteri (più un byte di controllo). È ideale per nomi, indirizzi ed email.
Tipi per Testi Lunghi
Quando VARCHAR non basta (il limite massimo è 65,535 byte), passiamo ai tipi TEXT:
- TINYTEXT: Fino a 255 caratteri.
- TEXT: Fino a 65,535 caratteri. Ideale per descrizioni di prodotti o commenti.
- MEDIUMTEXT: Fino a 16 MB.
- LONGTEXT: Fino a 4 GB. Usato per interi articoli di blog o log di sistema molto vasti.
Tipi Speciali: ENUM e SET
- ENUM: Permette di scegliere un valore da una lista predefinita. Ad esempio:
ENUM('Piccolo', 'Medio', 'Grande'). È molto efficiente perché internamente MySQL salva un numero, non la stringa. - SET: Simile a ENUM, ma permette di scegliere più valori dalla lista.
3. Tipi di Dato per Date e Ora
Gestire il tempo in un database è fondamentale per i log, le scadenze e l'analisi dei dati. MySQL offre diverse opzioni:
- DATE: Formato
YYYY-MM-DD. Usalo per le date di nascita o date di scadenza dove l'ora non è rilevante. - DATETIME: Formato
YYYY-MM-DD HH:MM:SS. Registra un punto preciso nel tempo. - TIMESTAMP: Simile a DATETIME, ma è legato al fuso orario (UTC). Viene spesso usato per le colonne
created_ateupdated_atperché può aggiornarsi automaticamente. - TIME: Formato
HH:MM:SS. Usato per durate o orari specifici. - YEAR: Memorizza solo l'anno in formato a 4 cifre.
Vediamo come implementare questi tipi in una tabella di ordini:
CREATE TABLE ordini (
ordine_id INT AUTO_INCREMENT PRIMARY KEY,
cliente_id INT,
data_ordine DATE NOT NULL, -- Solo la data
ora_consegna TIME, -- Solo l'orario
creato_il TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Automatico al momento dell'inserimento
aggiornato_il TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
In questo esempio, l'uso di CURRENT_TIMESTAMP permette al database di gestire autonomamente la data di creazione e l'ultimo aggiornamento senza che l'applicazione debba inviare questi dati manualmente.
4. Esempi Pratici: Casi d'Uso Reali
Per mettere in pratica quanto appreso, analizziamo tre scenari comuni di sviluppo web.
Caso A: Profilo Utente
Immaginiamo di creare un profilo utente per un social network. Quali tipi sceglieremmo?
- Username:
VARCHAR(30)(Lunghezza variabile, limite ragionevole). - Email:
VARCHAR(255)(Standard per email). - Password:
VARCHAR(255)(Le password hashate sono lunghe). - Data di Nascita:
DATE. - Genere:
ENUM('Maschio', 'Femmina', 'Altro', 'Preferisco non dire'). - Bio:
TEXT(L'utente può scrivere molto).
Caso B: E-commerce (Carrello)
- ID Prodotto:
INT UNSIGNED. - Quantità:
TINYINT UNSIGNED(Raramente un utente compra più di 127 pezzi dello stesso oggetto). - Prezzo Unitario:
DECIMAL(10, 2).
Caso C: Sistema di Log di Errore
- ID Errore:
BIGINT UNSIGNED(I log crescono velocemente,INTpotrebbe esaurirsi). - Livello Errore:
ENUM('INFO', 'WARNING', 'ERROR', 'CRITICAL'). - Messaggio Errore:
TEXT. - Data Ora:
TIMESTAMP.
5. Errori Comuni da Evitare
Durante la mia esperienza come sviluppatore, ho visto molti principianti cadere in queste trappole:
1. Usare VARCHAR per i numeri
Errore: Salvare l'età o il prezzo come VARCHAR.
Perché è sbagliato: Non puoi eseguire operazioni matematiche efficienti (SUM, AVG) direttamente nel database e l'ordinamento sarà alfabetico (es. "10" verrà prima di "2").
2. Usare TEXT per ogni stringa
Errore: Usare TEXT invece di VARCHAR per i nomi.
Perché è sbagliato: I campi TEXT sono memorizzati fuori dalla tabella principale, il che rende l'accesso leggermente più lento e impedisce l'uso di valori di default in alcune versioni di MySQL.
3. Dimenticare l'UNSIGNED
Errore: Usare INT per l'ID di un utente.
Perché è sbagliato: Un INT standard permette numeri negativi. Poiché un ID non sarà mai -5, usare INT UNSIGNED raddoppia virtualmente la capacità di memorizzazione dei numeri positivi.
4. Confondere DATETIME e TIMESTAMP
Errore: Usare TIMESTAMP per date molto lontane nel futuro (es. anno 2100).
Perché è sbagliato: Il tipo TIMESTAMP ha un limite massimo (l'anno 2038). Per date che superano tale limite, è obbligatorio usare DATETIME.
6. Tabella Riassuntiva per il Riferimento Rapido
Per aiutarti a scegliere, ecco uno schema sintetico:
| Tipo Dato | Quando usarlo | Esempio |
|---|---|---|
TINYINT |
Booleani, stati piccoli | is_active (0/1) |
INT |
ID, contatori standard | user_id |
BIGINT |
ID massivi, numeri enormi | tweet_id |
DECIMAL |
Denaro, precisione esatta | price (10.50) |
VARCHAR |
Testi di lunghezza variabile | email, name |
CHAR |
Testi di lunghezza fissa | country_code ('IT') |
TEXT |
Descrizioni, articoli | blog_content |
DATE |
Date senza orario | birth_date |
TIMESTAMP |
Log, date di sistema | created_at |
Prossimi Passi
Ora che conosci i tipi di dato, sei in grado di progettare tabelle efficienti e robuste. Ma come facciamo a collegare queste tabelle tra loro? Un database non è fatto di tabelle isolate, ma di relazioni.
Nella Lezione 5, studieremo le Chiavi Primarie (Primary Keys) e le Chiavi Esterne (Foreign Keys). Impareremo come creare legami tra le tabelle (ad esempio, collegare un ordine a un utente specifico) per evitare la ridondanza dei dati e mantenere l'integrità del sistema.
Esercizio consigliato: Prova a progettare lo schema di un database per una piccola biblioteca. Quali tipi di dato useresti per il titolo del libro, l'ISBN, l'autore, la data di pubblicazione e lo stato di disponibilità? Scrivi il codice SQL e prova a eseguirlo nel tuo ambiente di sviluppo!