CREATE TABLE în PostgreSQL

Tabele, scheme și tipuri (DDL) PostgreSQL 8.0+ (IF NOT EXISTS: 9.1+, GENERATED AS IDENTITY: 10+)

Creează un tabel nou, cu coloane, tipuri de date și constrângeri: PRIMARY KEY, NOT NULL, UNIQUE, CHECK, DEFAULT, FOREIGN KEY.

Sintaxă SQL
CREATE TABLE [IF NOT EXISTS] nume (
    coloana tip [constrângeri],
    ...,
    [CONSTRAINT nume_constrangere] constrângere_de_tabel
);

Ce face CREATE TABLE

CREATE TABLE definește un tabel: numele coloanelor, tipul fiecăreia și regulile pe care datele trebuie să le respecte. Regulile se numesc constrângeri și sunt verificate de PostgreSQL la fiecare INSERT și UPDATE, oricare ar fi aplicația care scrie în tabel.

Constrângerile de coloană se scriu după tip (email text NOT NULL UNIQUE). Cele care privesc mai multe coloane se scriu separat, la final (CHECK (data_sfarsit > data_inceput)). Dacă nu le dai un nume cu CONSTRAINT, PostgreSQL alege unul, de exemplu clienti_email_key sau clienti_pkey.

Pentru id-uri, varianta recomandată astăzi este GENERATED ALWAYS AS IDENTITY (standard SQL), în locul vechiului serial.

Parametri

Parametru Descriere
PRIMARY KEY Identifică unic fiecare rând. Implică NOT NULL și UNIQUE și creează automat un index.
NOT NULL Coloana nu poate fi goală (NULL).
UNIQUE Nu pot exista două rânduri cu aceeași valoare. Valorile NULL nu se consideră egale între ele (în afară de NULLS NOT DISTINCT, din PostgreSQL 15).
CHECK (condiție) Condiție care trebuie să fie adevărată pentru fiecare rând.
DEFAULT valoare Valoarea pusă când INSERT nu dă coloana, de exemplu now().
REFERENCES tabel (coloana) Cheie străină: valoarea trebuie să existe în celălalt tabel.
IF NOT EXISTS Nu dă eroare dacă tabelul există deja; afișează doar un NOTICE.

Ce returnează

Mesajul CREATE TABLE. Încălcarea unei constrângeri la inserare oprește comanda cu ERROR.

Exemple

Exemplul 1: Tabel de produse cu constrângeri

CREATE TABLE produse (
    id         integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    cod        text NOT NULL UNIQUE,
    nume       text NOT NULL,
    pret       numeric(10, 2) NOT NULL CONSTRAINT pret_pozitiv CHECK (pret > 0),
    stoc       integer NOT NULL DEFAULT 0,
    creat_la   timestamptz NOT NULL DEFAULT now()
);

Rezultat în psql

CREATE TABLE

Exemplul 2: Ce se întâmplă când datele nu respectă regulile

INSERT INTO produse (cod, nume, pret) VALUES ('PAINE-01', 'Pâine albă', 5.50);
INSERT INTO produse (cod, nume, pret) VALUES ('LAPTE-01', 'Lapte', -2);
INSERT INTO produse (cod, nume, pret) VALUES ('PAINE-01', 'Pâine neagră', 6);

Rezultat în psql

INSERT 0 1
ERROR:  new row for relation "produse" violates check constraint "pret_pozitiv"
DETAIL:  Failing row contains (2, LAPTE-01, Lapte, -2.00, 0, 2026-10-25 10:15:42.183614+02).
ERROR:  duplicate key value violates unique constraint "produse_cod_key"
DETAIL:  Key (cod)=(PAINE-01) already exists.

Exemplul 3: Constrângere pe mai multe coloane

Rezervarea trebuie să se termine după ce începe, iar o cameră nu poate avea două rezervări cu aceeași dată de început.

CREATE TABLE IF NOT EXISTS rezervari (
    id            integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    camera        integer NOT NULL,
    data_inceput  date NOT NULL,
    data_sfarsit  date NOT NULL,
    CONSTRAINT perioada_valida CHECK (data_sfarsit > data_inceput),
    CONSTRAINT o_rezervare_pe_zi UNIQUE (camera, data_inceput)
);

Rezultat în psql

CREATE TABLE

Greșeli frecvente

  • Folosești float sau real pentru bani. Sunt aproximative; pentru prețuri folosește numeric(10, 2).
  • Scrii numele de tabele cu litere mari fără ghilimele (CREATE TABLE Clienti): PostgreSQL le transformă în litere mici. Cu ghilimele ("Clienti") numele devine sensibil la majuscule și trebuie scris mereu cu ghilimele.
  • Lași constrângerile fără nume: mesajele de eroare devin greu de înțeles pentru constrângerile CHECK complicate. Dă-le nume clare cu CONSTRAINT.

Comenzi înrudite

  • FOREIGN KEY (REFERENCES): Cheia străină leagă două tabele: valoarea dintr-o coloană trebuie să existe în tabelul părinte, iar ON DELETE spune ce se întâmplă la ștergere.
  • ALTER TABLE: Modifică un tabel existent: adaugă, șterge sau redenumește coloane, schimbă tipul, valoarea implicită și constrângerile.
  • DROP TABLE: Șterge definitiv un tabel, cu toate datele, indecșii, triggerele și constrângerile lui.
  • CREATE TABLE AS și LIKE: Creează un tabel din rezultatul unei interogări (CREATE TABLE AS) sau copiind structura altui tabel (LIKE).