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
umožňuje následující CHECK
omezení syntaxe, pro obě tabulky, omezení a kolony omezení:
] CHECK (expr) ENFORCED]
volitelné symbol
určuje název omezení. Pokud je MySQL vynecháno, vygeneruje název z názvu tabulky, doslovný _chk_
a pořadové číslo (1, 2, 3, …). Názvy omezení mají maximální délku 64 znaků. Jsou citlivé na velká a malá písmena, ale nejsou citlivé na přízvuk.
expr
určuje omezení stavu jako logický výraz se musí vyhodnotit na TRUE
nebo UNKNOWN
(za NULL
hodnoty) pro každý řádek tabulky. Pokud se podmínka vyhodnotí na FALSE
, selže a dojde k porušení omezení. Účinek porušení závisí na provedeném prohlášení, jak je popsáno dále v této části.
volitelná klauzule o vynucování označuje, zda je omezení vynuceno:
-
Pokud je vynechán nebo zadán jako
ENFORCED
, omezení je vytvořen a prosazován. -
Pokud je zadáno jako
NOT ENFORCED
, omezení je vytvořeno, ale není vynuceno.
CHECK
omezení je uvedeno buď jako tabulku omezení nebo sloupec omezení:
-
tabulce constraint nezobrazí ve sloupci definice a může odkazovat na libovolné sloupce tabulky nebo sloupce. Dopředné odkazy jsou povoleny na sloupce, které se objeví později v definici tabulky.
-
omezení sloupce se objeví v definici sloupce a může odkazovat pouze na tento sloupec.
Zvážit tato definice tabulky:
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));
definice zahrnuje tabulka omezení a kolony omezení, v pojmenované a nepojmenované formátů:
-
první omezení je tabulka omezení: dochází mimo jakékoliv definice sloupce, tak to může (a má) odkazují na více sloupců tabulky. Toto omezení obsahuje odkazy na sloupce, které ještě nebyly definovány. Není zadán žádný název omezení, takže MySQL vygeneruje název.
-
další tři omezení jsou omezení sloupců: každé se vyskytuje v definici sloupce, a proto může odkazovat pouze na definovaný sloupec. Jedno z omezení je pojmenováno explicitně. MySQL vygeneruje název pro každou z dalších dvou.
-
poslední dvě omezení jsou omezení tabulky. Jeden z nich je pojmenován explicitně. MySQL vygeneruje název pro ten druhý.
Jak již bylo zmíněno, MySQL generuje název pro CHECK
omezení uvedeno bez. Chcete-li zobrazit názvy vytvořené pro předchozí definice tabulky, použijte 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
SQL standard určuje, že všechny typy omezení (primární klíč, unikátní index, cizí klíč, check) patří do stejného jmenného prostoru. V MySQL má každý typ omezení vlastní jmenný prostor podle schématu (databáze). Proto CHECK
názvy omezení musí být jedinečné pro schéma; žádné dvě tabulky ve stejném schématu nemohou sdílet CHECK
název omezení. (Výjimka: TEMPORARY
tabulka skrývá non-TEMPORARY
tabulka se stejným názvem, tak to může mít stejnou CHECK
omezení jmen stejně.)
začátek generovaných názvů omezení s názvem tabulky pomáhá zajistit jedinečnost schématu, protože názvy tabulek musí být také jedinečné v rámci schématu.
CHECK
výrazy podmínek musí dodržovat následující pravidla. K chybě dochází, pokud výraz obsahuje zakázané konstrukce.
-
Nongenerated a generované sloupce jsou povoleny, s výjimkou sloupce s
AUTO_INCREMENT
atribut a sloupce v jiných tabulkách. -
literály, deterministické vestavěné funkce a operátory jsou povoleny. Funkce je deterministická, pokud při stejných datech v tabulkách vytváří více vyvolání stejný výsledek, nezávisle na připojeném uživateli. Příklady funkcí, které jsou nedeterministické a nepodaří tuto definici:
CONNECTION_ID()
CURRENT_USER()
NOW()
. -
uložené funkce a uživatelem definované funkce nejsou povoleny.
-
uložené parametry procedury a funkce nejsou povoleny.
-
proměnné (systémové proměnné, uživatelem definované proměnné a uložené lokální proměnné programu) nejsou povoleny.
-
poddotazy nejsou povoleny.
Cizí klíč, referenční akce (ON UPDATE
ON DELETE
), jsou zakázány na sloupce v CHECK
omezení. 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
. Pokud dojde k chybě, zpracování změn již aplikuje se liší pro transakční a nontransactional skladování motory, a také závisí na tom, zda přísná SQL režim je v podstatě, jak je popsáno v Přísném Režimu SQL.
CHECK
omezení jsou vyhodnocovány pro INSERT IGNORE
UPDATE IGNORE
LOAD DATA ... IGNORE
LOAD XML ... IGNORE
prohlášení a varování dojde v případě, že omezení vyhodnocen FALSE
. Vložení nebo aktualizace pro jakýkoli urážlivý řádek je přeskočena.
Pokud výraz omezení vyhodnotí datový typ, který se liší od deklarovaného typu sloupce, implicitní donucení k deklarovanému typu nastane podle obvyklých pravidel převodu typu MySQL. Viz bod 12.3 – „převod typu v hodnocení výrazů“. Pokud převod typu selže nebo má za následek ztrátu přesnosti, dojde k chybě.
Constraint expression evaluation používá SQL režim platný v době vyhodnocení. Pokud některá složka výrazu závisí na režimu SQL, mohou nastat různé výsledky pro různá použití tabulky, pokud není režim SQL při všech použitích stejný.