De-a lungul deceniilor, dezvoltatorii PostgreSQL au folosit tipul de dată SERIAL (sau BIGSERIAL) pentru chei primare auto-incrementale. Deși familiar, SERIAL nu este o caracteristică standard SQL, ci doar un macro syntactic care ascunde o secvență independentă. Începând cu PostgreSQL 10, standardul oficial SQL:2008 IDENTITY COLUMNS a devenit abordarea recomandată oficial de comunitatea PostgreSQL.
Definirea unei tabele moderne cu Identity și Generated Columns
CREATE TABLE comenzi_online (
-- Cheie primară conformă cu standardul internațional SQL
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
numar_comanda VARCHAR(50) NOT NULL,
subtotal NUMERIC(10, 2) NOT NULL,
cota_tva NUMERIC(4, 2) DEFAULT 0.19,
-- Coloană Calculată Stocată (Generated Column - PostgreSQL 12+)
total_cu_tva NUMERIC(10, 2) GENERATED ALWAYS AS (
ROUND(subtotal * (1 + cota_tva), 2)
) STORED
);
-- Inserarea devine curată și sigură:
INSERT INTO comenzi_online (numar_comanda, subtotal)
VALUES ('CMD-2026-001', 100.00);
-- PostgreSQL a calculat automat valoarea 119.00 în coloana 'total_cu_tva'!
SELECT * FROM comenzi_online;
De ce GENERATED AS IDENTITY este superior lui SERIAL?
| Aspect | Vechiul SERIAL | GENERATED ALWAYS AS IDENTITY |
|---|---|---|
| Standard SQL | Proprietar PostgreSQL (non-standard). | Standard internațional SQL:2008 (compatibil Oracle, DB2 etc.). |
| Gestiunea Permisiunilor | Necesită permisiuni separate pe secvența ascunsă din spate. | Permisiunile sunt legate direct de tabel. |
| Protecție împotriva inserărilor accidentale | Poate fi suprascris ușor cu INSERT INTO tab (id) VALUES (5), ducând ulterior la erori de cheie duplicată. |
Clauza ALWAYS blochează valorile manuale accidentale (necesită explicit OVERRIDING SYSTEM VALUE). |
| Comportament la COPY / Migrare | Secvențele pot rămâne desincronizate. | Integrare nativă curată cu utilitarele de backup și replicare logică. |
Reguli pentru Coloanele Generate (STORED)
- O coloană generată este calculată automat la momentul fiecărui
INSERTsauUPDATEși este stocată fizic pe disc (în prezent, PostgreSQL suportă exclusiv clauzaSTORED). - Expresia generatoare poate folosi orice alte coloane din același rând, dar nu poate referenția alte tabele sau subinterogări.
- Coloanele generate pot fi indexate direct cu indecși B-Tree sau GIN, oferind viteze maxime de căutare fără cost de recalculare la interogare!