13.1.20.6 CHECK Constraints
Prior to MySQL 8.0.16, CREATE TABLE
permits only the following limited version of table CHECK
constraint syntax, which is parsed and ignored:
CHECK (expr)
As of MySQL 8.0.16, CREATE TABLE
permits the core features of table and column CHECK
constraints, for all storage engines. CREATE TABLE
zezwala na następująceCHECK
składnia ograniczeń, zarówno dla ograniczeń tabel, jak i ograniczeń kolumn:
] CHECK (expr) ENFORCED]
opcjonalnysymbol
określa nazwę ograniczenia. Jeśli zostanie pominięte, MySQL generuje nazwę z nazwy tabeli, literalny _chk_
I liczbę porządkową (1, 2, 3,…). Nazwy ograniczeń mają maksymalną długość 64 znaków. Rozróżnia się wielkość liter, ale nie akcent.
expr
Określa warunek ograniczenia jako wyrażenie logiczne, które musi obliczyć wartośćTRUE
lubUNKNOWN
(dla wartościNULL
) dla każdego wiersza tabeli. Jeśli warunek zostanie oceniony na FALSE
, nie powiedzie się i wystąpi naruszenie ograniczeń. Efekt naruszenia zależy od wykonania oświadczenia, jak opisano w dalszej części tej sekcji.
fakultatywna klauzula wykonalności wskazuje, czy ograniczenie jest egzekwowane:
-
Jeśli zostanie pominięte lub określone jako
ENFORCED
, zostanie utworzone i wymuszone ograniczenie. -
Jeśli podano
NOT ENFORCED
, ograniczenie jest tworzone, ale nie wymuszane.
aCHECK
ograniczenie jest określone jako ograniczenie tabeli lub kolumny:
-
ograniczenie tabeli nie pojawia się w definicji kolumny i może odnosić się do dowolnej kolumny lub kolumn tabeli. Dozwolone są odwołania do kolumn pojawiających się później w definicji tabeli.
-
ograniczenie kolumny pojawia się w definicji kolumny i może odnosić się tylko do tej kolumny.
rozważ tę definicję tabeli:
CREATE TABLE t1( CHECK (c1 <> c2), c1 INT CHECK (c1 > 10), c2 INT CONSTRAINT c2_positive CHECK (c2 > 0), c3 INT CHECK (c3 < 100), CONSTRAINT c1_nonzero CHECK (c1 <> 0), CHECK (c1 > c3));
definicja zawiera ograniczenia tabel i ograniczeń kolumn, w nazwanych i nienazwanych formatach:
-
pierwsze ograniczenie jest ograniczeniem tabeli: występuje poza dowolną definicją kolumny, więc Can (I does) odnosi się do wielu kolumn tabeli. To ograniczenie zawiera odniesienia do kolumn, które nie zostały jeszcze zdefiniowane. Nie podano nazwy ograniczenia, więc MySQL generuje nazwę.
-
następne trzy ograniczenia są ograniczeniami kolumn: każdy występuje w definicji kolumny, a zatem może odnosić się tylko do zdefiniowanej kolumny. Jedno z ograniczeń jest nazwane jawnie. MySQL generuje nazwę dla każdego z dwóch pozostałych.
-
dwa ostatnie ograniczenia są ograniczeniami tabeli. Jeden z nich jest nazwany wprost. MySQL generuje nazwę dla drugiego.
Jak wspomniano, MySQL generuje nazwę dla dowolnego ograniczenia CHECK
bez niego. Aby zobaczyć nazwy wygenerowane dla poprzedniej definicji tabeli, użyj SHOW CREATE TABLE
:
mysql> SHOW CREATE TABLE t1\G*************************** 1. row *************************** Table: t1Create Table: CREATE TABLE `t1` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL, `c3` int(11) DEFAULT NULL, CONSTRAINT `c1_nonzero` CHECK ((`c1` <> 0)), CONSTRAINT `c2_positive` CHECK ((`c2` > 0)), CONSTRAINT `t1_chk_1` CHECK ((`c1` <> `c2`)), CONSTRAINT `t1_chk_2` CHECK ((`c1` > 10)), CONSTRAINT `t1_chk_3` CHECK ((`c3` < 100)), CONSTRAINT `t1_chk_4` CHECK ((`c1` > `c3`))) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
standard SQL określa, że wszystkie typy ograniczeń (klucz podstawowy, unikalny indeks, klucz obcy, sprawdź) należą do tej samej przestrzeni nazw. W MySQL każdy typ ograniczenia ma swoją własną przestrzeń nazw dla schematu (bazy danych). W związku z tymCHECK
nazwy ograniczeń muszą być unikalne dla danego schematu; żadne dwie tabele w tym samym schemacie nie mogą współdzielić nazwy ograniczenia CHECK
. (Wyjątek: tabela TEMPORARY
ukrywa tabelę inną niżTEMPORARY
o tej samej nazwie, więc może mieć również te same nazwy ograniczeń CHECK
.)
początek generowanych nazw ograniczeń z nazwą tabeli pomaga zapewnić unikalność schematu, ponieważ nazwy tabel również muszą być unikalne w ramach schematu.
CHECK
wyrażenia warunków muszą być zgodne z następującymi regułami. Błąd występuje, gdy wyrażenie zawiera niedozwolone konstrukcje.
-
dozwolone są kolumny Niezgenerowane i wygenerowane, z wyjątkiem kolumn z atrybutem
AUTO_INCREMENT
I kolumn w innych tabelach. -
dozwolone są literały, deterministyczne wbudowane funkcje i operatory. Funkcja jest deterministyczna, jeżeli, biorąc pod uwagę te same dane w tabelach, wielokrotne wywołania dają ten sam wynik, niezależnie od podłączonego użytkownika. Przykłady funkcji, które nie są zgodne z tą definicją:
CONNECTION_ID()
CURRENT_USER()
NOW()
. -
funkcje przechowywane i funkcje zdefiniowane przez użytkownika są niedozwolone.
-
procedura składowana i parametry funkcji są niedozwolone.
-
zmienne (zmienne systemowe, zmienne zdefiniowane przez użytkownika i przechowywane zmienne lokalne programu) nie są dozwolone.
-
zapytania podrzędne są niedozwolone.
akcje referencyjne klucza zagranicznego (ON UPDATE
ON DELETE
) są zabronione na kolumnach używanych w ograniczeniach CHECK
. Likewise, CHECK
constraints are prohibited on columns used in foreign key referential actions.
CHECK
constraints are evaluated for INSERT
UPDATE
REPLACE
LOAD DATA
, and LOAD XML
statements and an error occurs if a constraint evaluates to FALSE
. Jeśli wystąpi błąd, obsługa już zastosowanych zmian różni się dla transakcyjnych i nietransakcyjnych silników pamięci masowej, a także zależy od tego, czy obowiązuje tryb strict SQL, jak opisano w trybie Strict SQL.
CHECK
ograniczenia są obliczane dla INSERT IGNORE
UPDATE IGNORE
LOAD DATA ... IGNORE
I LOAD XML ... IGNORE
I ostrzeżenie pojawia się, gdy ograniczenie ma wartość FALSE
. Wstawianie lub aktualizacja dla dowolnego błędnego wiersza jest pomijane.
Jeśli wyrażenie constraint zwraca typ danych, który różni się od zadeklarowanego typu kolumny, implicit coercion do zadeklarowanego typu występuje zgodnie ze zwykłymi regułami konwersji typów MySQL. Patrz sekcja 12.3 „Konwersja typów w ocenie wyrażeń”. Jeśli konwersja typu nie powiedzie się lub spowoduje utratę precyzji, wystąpi błąd.
Obliczanie wyrażenia ograniczającego używa trybu SQL w czasie obliczania. Jeżeli dowolny składnik wyrażenia zależy od trybu SQL, to mogą wystąpić różne wyniki dla różnych zastosowań tabeli, chyba że tryb SQL jest taki sam podczas wszystkich zastosowań.