programowanieFullstack developer

Czym są ograniczenia (constraints) w SQL, jakie są ich typy i jak pomagają unikać błędów w logice aplikacji? Podaj przykłady użycia.

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

Ograniczenia (constraints) — to ograniczenia integralności nakładane na kolumny lub tabele w celu automatycznej kontroli dopuszczalności wartości. Pozwalają one:

  • Chronić dane przed niewłaściwym wprowadzeniem;
  • Przenieść część logiki aplikacyjnej do bazy (bardziej niezawodne i szybsze);
  • Automatycznie sprawdzać warunki przy wstawianiu, aktualizacji lub usuwaniu.

Rodzaje podstawowych ograniczeń:

  • PRIMARY KEY — unikalny identyfikator, zabrania duplikacji i NULL.
  • UNIQUE — zabrania duplikacji wartości w jednej kolumnie.
  • FOREIGN KEY — integralność referencyjna, powiązanie z inną tabelą.
  • CHECK — sprawdzanie dowolnego wyrażenia.
  • NOT NULL — zakaz NULL wartości w kolumnie.

Przykład:

CREATE TABLE orders ( id SERIAL PRIMARY KEY, user_id INT REFERENCES users(id), -- klucz obcy price DECIMAL(10,2) CHECK (price > 0), created_at TIMESTAMP NOT NULL );

Pytanie podchwytliwe

"Czy klucz unikalny (UNIQUE) jest automatycznie NULL-SAFE, wykluczając dowolną liczbę wartości NULL w kolumnie?"

W rzeczywistości, w większości systemów DBMS (np. PostgreSQL, MySQL) ograniczenie UNIQUE dopuszcza kilka wierszy z wartością NULL, ponieważ NULL traktowane jest jako "nieznane". Często prowadzi to do niewidocznego duplikowania pustych wartości.

Przykład:
CREATE TABLE test ( id INT PRIMARY KEY, code VARCHAR(10) UNIQUE ); INSERT INTO test (id, code) VALUES (1, NULL), (2, NULL); -- przejdzie

Przykłady rzeczywistych błędów z powodu braku wiedzy o szczegółach tematu


Historia

Aplikacja umożliwiała rejestrację za pomocą e-maila, kolumna była UNIQUE, ale NIE NOT NULL — w tabeli znalazło się kilkunastu użytkowników z NULL-email, co spowodowało problemy przy integracji z zewnętrznymi usługami.


Historia

W systemie zamówień biletów zapomniano dodać FOREIGN KEY do tabeli payments — w rezultacie pojawiły się płatności, które nie były powiązane z żadnym zamówieniem, co uniemożliwiało zwroty użytkownikom.


Historia

CHECK-constraint dla zniżki: discount > 0. Zapomniano o granicznej sytuacji dla 0. W efekcie system przyjmował tylko zniżki większe od 0, a brak zniżki (0) łamał logikę biznesową.