Ograniczenie (ang. constraint) to reguła, którą nakładasz na kolumnę lub całą tabelę w bazie danych, żeby pilnowała poprawności zapisywanych danych. Mówiąc wprost: to strażnik na wejściu do tabeli, który odrzuca wartości łamiące zasady, jeszcze zanim trafią do dysku. Dzięki temu nie musisz wierzyć aplikacji na słowo — sama baza dba o to, żeby nie wpadło do niej nic bezsensownego.
Do czego to służy
Ograniczenia przenoszą część logiki sprawdzania danych z kodu aplikacji do silnika bazy. To istotne, bo do jednej bazy potrafi pukać kilka aplikacji, skryptów i ludzi z konsolą. Gdyby walidacja siedziała tylko w kodzie, każdy z tych kanałów musiałby ją powielać — a wystarczy jeden, który tego nie zrobi, i masz śmieci w tabeli. Constraint wymusza regułę raz, niezależnie od tego, kto wysyła INSERT czy UPDATE.
Najczęściej spotkasz kilka rodzajów. NOT NULL zabrania pustej wartości w kolumnie. UNIQUE pilnuje, żeby wartości się nie powtarzały (np. e-mail użytkownika). PRIMARY KEY łączy unikalność z NOT NULL i wskazuje klucz główny wiersza. FOREIGN KEY wymusza, by wartość wskazywała na istniejący wiersz w innej tabeli (integralność referencyjna). CHECK sprawdza dowolny warunek logiczny, a DEFAULT podstawia wartość, gdy żadnej nie podasz.
Przykład z praktyki
Załóżmy, że w PostgreSQL tworzysz tabelę użytkowników. Chcesz, żeby każdy miał unikalny e-mail, niepusty login i wiek co najmniej 18 lat:
CREATE TABLE uzytkownicy (id SERIAL PRIMARY KEY, login TEXT NOT NULL, email TEXT UNIQUE, wiek INT CHECK (wiek >= 18));
Teraz próba INSERT z drugim takim samym e-mailem albo wiekiem 15 skończy się błędem i odrzuceniem operacji — baza nie da się oszukać. Constraint możesz też dodać później przez ALTER TABLE ... ADD CONSTRAINT, co przydaje się, gdy reguły dochodzą z czasem.
Na co uważać
Pierwszy klasyk: dodajesz NOT NULL albo CHECK do tabeli, w której już są dane łamiące regułę — baza odrzuci zmianę, bo nie ma jak pogodzić nowej zasady ze starymi wierszami. Najpierw posprzątaj dane. Drugi mit: że NULL w kolumnie UNIQUE liczy się jak zwykła wartość. W większości baz (PostgreSQL, Oracle) wiele NULL-i przejdzie, bo NULL nie jest „równy” innemu NULL. Trzecia pułapka: poleganie wyłącznie na walidacji w aplikacji — to wygodne dla komunikatów dla użytkownika, ale to constraint w bazie jest ostatnią linią obrony.
Pojęcia powiązane: klucz główny (primary key), klucz obcy (foreign key), integralność danych, indeks, schemat bazy danych, normalizacja, transakcja.