このページは機械翻訳したものです。
MySQL 8.0.16 より前のCREATE TABLE では、次の限定バージョンのテーブルCHECK 制約構文のみが許可されていました。この構文は解析され、無視されます:
CHECK (expr) MySQL 8.0.16 の時点で、CREATE TABLE は、すべてのストレージエンジンに対して、テーブルおよびカラムのCHECK 制約のコア機能を許可します。CREATE TABLE では、テーブル制約とカラム制約の両方に対して、次のCHECK 制約構文を使用できます:
[CONSTRAINT [symbol]] CHECK (expr) [[NOT] ENFORCED] オプションのsymbol では、制約の名前を指定します。 省略すると、MySQL はテーブル名、リテラル_chk_および序数 (1、2、3 など) から名前を生成します。 制約名の最大長は 64 文字です。 大/小文字は区別されますが、アクセントは区別されません。
expr では、制約条件をブール式として指定します。この式は、テーブルの各行に対してTRUE またはUNKNOWN (NULL 値の場合) に評価される必要があります。 条件がFALSE に評価されると、失敗し、制約違反が発生します。 違反の影響は、このセクションの後半で説明するように、実行されるステートメントによって異なります。
オプションの施行句は、制約が施行されるかどうかを示します:
省略するか、
ENFORCEDとして指定すると、制約が作成されて適用されます。NOT ENFORCEDとして指定した場合、制約は作成されますが、施行されません。
CHECK 制約は、テーブル制約またはカラム制約のいずれかとして指定されます:
テーブル制約はカラム定義内には表示されず、任意のテーブルのカラムを参照できます。 前方参照は、後でテーブル定義に表示されるカラムに対して許可されます。
カラム制約はカラム定義内に表示され、そのカラムのみを参照できます。
このテーブル定義について考えます。
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 は名前を生成します。
次の 3 つの制約はカラム制約です: それぞれがカラム定義内で発生するため、参照できるのは定義されているカラムのみです。 いずれかの制約に明示的に名前が付けられます。 MySQL では、それぞれの名前が生成されます。
最後の 2 つの制約はテーブル制約です。 これらのいずれかに明示的に名前が付けられます。 MySQL により、他方の名前が生成されます。
前述のように、MySQL は、指定されていない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 制約で使用されるカラムでは禁止されています。 同様に、CHECK 制約は、外部キー参照アクションで使用されるカラムでは禁止されています。
CHECK 制約は、INSERT,UPDATE,REPLACE,LOAD DATA およびLOAD XML ステートメントに対して評価され、制約がFALSE と評価されるとエラーが発生します。 エラーが発生した場合、すでに適用されている変更の処理は、厳密な SQL モード で説明されているように、トランザクションストレージエンジンと非トランザクションストレージエンジンで異なり、厳密な SQL モードが有効になっているかどうかによっても異なります。
CHECK 制約は、INSERT IGNORE,UPDATE IGNORE,LOAD DATA ... IGNORE およびLOAD XML ... IGNORE ステートメントに対して評価され、制約がFALSE と評価されると警告が発生します。 問題のある行の挿入または更新はスキップされます。
制約式が宣言されたカラム型とは異なるデータ型に評価された場合、宣言された型への暗黙的な強制は、通常の MySQL 型変換ルールに従って行われます。セクション12.3「式評価での型変換」を参照してください。 型変換が失敗した場合、または精度が失われた場合は、エラーが発生します。
制約式の評価では、評価時に有効な SQL モードが使用されます。 式のいずれかのコンポーネントが SQL モードに依存している場合、すべての使用中に SQL モードが同じでないかぎり、テーブルの使用方法によって結果が異なることがあります。