Poznajemy ostatni rodzaj constraints, w dodatku w Laravelu to będziemy robić inaczej, za pomocą walidacji, więc bardziej lekcja dla chętnych.

Ok, do bazy danych (testowej, nie Laravelowej) i używamy tej komendy:

ALTER TABLE `people` 
ADD CONSTRAINT PersonAge_chk CHECK (age > 17);

Teraz próbujemy zmienić komuś wiek na mniejszy niż 18 – nie wyjdzie.

Podobne ćwiczenie:

ALTER TABLE `people` 
ADD CONSTRAINT PersonTooOld_chk CHECK (age < 150);

Ok, wypróbujmy teraz dodajmy unique do name:

ALTER TABLE `people` 
ADD CONSTRAINT unique_name UNIQUE (name);

Tutaj dodajemy nazwane constrainty tabelkowe, ale dodajmy inline constraint kolumnowy, defaulta sobie dodajmy do age:

ALTER TABLE `people` 
ALTER COLUMN age 
SET DEFAULT 16;

I przechodzi, chociaż check mamy ustawiony. Te checki to nie jest lekarstwo na wszystkie problemy.

Zmieńmy default na 19:

ALTER TABLE `people` 
ALTER COLUMN age 
SET DEFAULT 19;

A teraz dropnijmy ten default:

ALTER TABLE `people` 
ALTER COLUMN age 
DROP DEFAULT;

Ok, teraz zobaczmy jak te constrainty tworzy się z create table:

CREATE TABLE Persons (
    ID int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Age int,
    CHECK (Age>=18)
);

Tu mamy na poziomie tabelkowym, nienazwany, oddziałuje na jedną kolumnę.

Teraz nazwany na wiele kolumn:

CREATE TABLE Persons (
    ID int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Age int,
    City varchar(255),
    CONSTRAINT CHK_Person CHECK (Age>=18 AND City='Sandnes')
);

Teraz jak się dodaje (nienazwany) do już istniejącej tabeli i kolumny:

ALTER TABLE Persons
ADD CHECK (Age>=18);

A jak się nadaje nazwany:

ALTER TABLE Persons
ADD CONSTRAINT CHK_PersonAge CHECK (Age>=18 AND City='Sandnes');

Nazwany ma to do siebie, że można go dropnąć:

ALTER TABLE Persons
DROP CHECK CHK_PersonAge;

Różnicę między nienazwanym i nazwanym oraz o zasięgu tabelowym oraz inlinem sobie jeszcze raz przypomnijmy, na przykładzie unique.

Nienazwany constraint unique, zasięg tabelowy:

CREATE TABLE Persons (
    ID int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Age int,
    UNIQUE (ID)
);

Nazwany unique, zasięg tabelowy:

CREATE TABLE Persons (
    ID int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Age int,
    CONSTRAINT UC_Person UNIQUE (ID,LastName)
);

Unique tworzy indeks (jak inaczej byłby w stanie spełniać swoje zadanie i sprawdzać, czy w tabeli nie ma już takiej wartości jak ta, którą ktoś próbuje wprowadzić) więc w MySQL dropimy go tak:

ALTER TABLE Persons
DROP INDEX UC_Person;

A w innych SQLach zazwyczaj tak:

ALTER TABLE Persons
DROP CONSTRAINT UC_Person;

A teraz przykład unique ale inline, o zasięgu kolumnowym:

CREATE TABLE Persons (
    ID int NOT NULL UNIQUE,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Age int
);

Najlepszymi przykładami inline constraints są not null oraz default. Dodajemy je (do już utworzonej tabeli i kolumny) w taki sposób:

ALTER TABLE MyTable 
ALTER COLUMN foo 
SET DEFAULT 'bar';

Czyli alter table alter column. Dropimy tak:

ALTER TABLE MyTable 
ALTER COLUMN foo 
DROP DEFAULT;

Czyli też alter table alter column. Z kolei (nazwane) constrainty o zasięgu tabelkowym dodajemy tak:

ALTER TABLE Persons
ADD CONSTRAINT CHK_PersonAge CHECK (Age>=18 AND City='Sandnes');

Dropimy na różne sposoby, zależy i od rodzaju constrainta i od rodzaju SQLa. Trochę praktyki będzie potrzebne, aby to opanować i się nie mylić, ale mam nadzieję, że powoli się temat rozjaśnił.