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ł.