Coloanele Generate (Generated Columns) sunt coloane speciale a căror valoare este calculată automat de către MySQL pe baza unei expresii deterministe aplicate asupra altor coloane din același rând. Ele elimină necesitatea trigger-elor complicate și garantează că datele calculate rămân întotdeauna sincronizate.
MySQL oferă două tipuri de coloane generate: VIRTUAL (valoarea este calculată în zbor la citire și nu ocupă spațiu pe disc) și STORED (valoarea este calculată la inserare/modificare și este salvată fizic pe disc alături de rând).
CREATE TABLE comenzi (
id INT PRIMARY KEY AUTO_INCREMENT,
pret_unitar DECIMAL(10,2) NOT NULL,
cantitate INT NOT NULL,
date_livrare JSON,
-- Coloană calculată automat în memorie (VIRTUAL):
total_linie DECIMAL(10,2) AS (pret_unitar * cantitate) VIRTUAL,
-- Extragerea unui câmp JSON într-o coloană generată pentru a putea fi indexată!
oras_livrare VARCHAR(50) AS (JSON_UNQUOTE(JSON_EXTRACT(date_livrare, '$.oras'))) STORED,
-- Putem pune un index B-Tree clasic pe coloana generată!
INDEX idx_oras (oras_livrare)
);
-- Inserare simplă (nu trimitem valori pentru coloanele generate!):
INSERT INTO comenzi (pret_unitar, cantitate, date_livrare)
VALUES (150.00, 3, '{"oras": "București", "cod_postal": "010101"}');
SELECT total_linie, oras_livrare FROM comenzi;
-- Returnează: 450.00 | București
În MySQL 8.0 poți crea un index direct pe o funcție fără a mai declara explicit o coloană generată:
-- Creează un index direct pe adresa de email convertită la minuscule:
CREATE INDEX idx_email_lower ON utilizatori ((LOWER(email)));
-- Această interogare va folosi indexul în mod automat la căutare rapidă:
SELECT * FROM utilizatori WHERE LOWER(email) = 'ion@exemplu.ro';
VIRTUAL vs. STORED
| Caracteristică | VIRTUAL | STORED |
|---|---|---|
| Spațiu pe disc | Zero octeți suplimentari (se calculează în RAM la citire). | Ocupă spațiu fizic pe disc în fișierul .ibd. |
| Cost la scriere (INSERT/UPDATE) | Zero cost suplimentar. | Se recalculează și se scrie pe disc la fiecare modificare. |
| Indexare B-Tree | Permisă în InnoDB (MySQL menține indexul în memorie). | Permisă nativ pe disc. |