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
CHECK
制約構文を許可します。
] CHECK (expr) ENFORCED]
オプションのsymbol
制約の名前を指定します。 省略された場合、MySQLはテーブル名から名前、リテラル_chk_
TRUE
UNKNOWN
NULL
FALSE
と評価されると、失敗し、制約違反が発生します。 違反の影響は、このセクションの後半で説明するように、実行されるステートメントによって異なります。
オプションのenforcement句は、制約が強制されるかどうかを示します:
-
省略された場合、または
ENFORCED
NOT ENFORCED
として指定された場合、制約は作成されますが、強制されません。
aCHECK
制約は、テーブル制約または列制約のいずれかとして指定されます。
-
テーブル制約は列定義内に 前方参照は、テーブル定義の後に表示される列に対して許可されます。
-
列制約は列定義内に表示され、その列のみを参照できます。
このテーブル定義を考えてみましょう。
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));
定義には、名前付きおよび名前のない形式のテーブル制約と列制約が含まれています。
-
最初の制約はテーブル制約です。テーブルの列。 この制約には、まだ定義されていない列への前方参照が含まれています。 制約名は指定されていないため、MySQLは名前を生成します。
-
次の三つの制約は列制約です。 制約の1つに明示的な名前が付けられています。 MySQLは、他の2つのそれぞれの名前を生成します。
-
最後の2つの制約はテーブル制約です。 そのうちの1つは明示的に名前が付けられています。 MySQLは他の名前の名前を生成します。前述のように、MySQLは
CHECK
CHECK
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標準では、すべてのタイプの制約(主キー、一意インデックス、外部キー、 MySQLでは、各制約タイプには、スキーマ(データベース)ごとに独自の名前空間があります。 したがって、
CHECK
CHECK
TEMPORARY
TEMPORARY
CHECK
制約名も持つことができます。)生成された制約名をテーブル名で開始すると、テーブル名もスキーマ内で一意でなければならないため、スキーマの一意性を確保できます。
CHECK
条件式は、次の規則に従わなければなりません。 式に許可されていない構造体が含まれている場合、エラーが発生します。-
非生成列と生成列は許可されますが、
AUTO_INCREMENT
属性を持つ列と他のテーブルの列を除きます。 -
リテラル、確定的な組み込み関数、および演算子が許可されます。 テーブル内の同じデータが与えられた場合、複数の呼び出しが接続されているユーザーとは無関係に同じ結果を生成する場合、関数は決定的です。 非決定的であり、この定義に失敗する関数の例:
CONNECTION_ID()
CURRENT_USER()
NOW()
。 -
ストアド関数およびユーザー定義関数は許可されていません。
-
ストアドプロシージャおよび関数パラメーターは許可されません。
-
変数(システム変数、ユーザー定義変数、および格納されたプログラムローカル変数)は許可されていません。
-
サブクエリは許可されていません。
外部キー参照アクション(
ON UPDATE
ON DELETE
CHECK
制約で使用される列で禁止されています。 Likewise,CHECK
constraints are prohibited on columns used in foreign key referential actions.CHECK
constraints are evaluated forINSERT
UPDATE
REPLACE
LOAD DATA
, andLOAD XML
statements and an error occurs if a constraint evaluates toFALSE
. エラーが発生した場合、既に適用されている変更の処理は、トランザクション-ストレージ-エンジンと非トランザクション-ストレージ-エンジンで異なり、”Strict SQLモード”CHECK
INSERT IGNORE
UPDATE IGNORE
LOAD DATA ... IGNORE
LOAD XML ... IGNORE
FALSE
に評価されます。 問題のある行の挿入または更新はスキップされます。 制約式が宣言された列型とは異なるデータ型に評価される場合、宣言された型への暗黙的な強制は、通常のMySQLの型変換規則に従って行われます。 項12.3「式の評価での型変換」を参照してください。 型変換が失敗した場合、または精度が失われた場合は、エラーが発生します。注制約式の評価は、評価時に有効なSQLモードを使用します。 式のいずれかのコンポーネントがSQLモードに依存している場合、すべての使用中にSQLモードが同じでない限り、テーブルの使用ごとに異なる結果が発生す
-
div