メインコンテンツへスキップ

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
MySQL は CHECK 制約を適用します。古いバージョンでは構文は受け入れられても黙って無視されていました。この動作は、PostgreSQL から移行する多くの開発者を驚かせました。

CHECK 制約の定義

CHECK 制約は、列と一緒にインラインで追加するか、テーブルレベルの制約として追加します。
または、列定義と一緒にインラインで指定します。
チェック式が複数の列にまたがる場合は、テーブルレベルの制約が必要です。

適用

MySQL は INSERT と UPDATE で CHECK 制約を適用します。違反すると ERROR 3819 (HY000): Check constraint 'name' is violated. が返されます。
エラーメッセージには制約名が含まれます。これが、制約に名前を付ける手間をかける価値がある理由です。 CHECK 制約は DELETE では評価されません。また、既存のテーブルに制約自体を追加するときに再評価されることもありません。制約に違反する既存データを持つテーブルに制約を追加すると、すぐに失敗します。

制約の追加と削除

既存のテーブルに制約を追加します。
名前付き制約を削除します。
テーブルのすべての制約を一覧表示します。

適用の無効化

特定の制約を削除せずに無効にします。
再度有効にします。
NOT ENFORCED は、検証を一時的に回避する必要があるデータ移行の際に役立ちます。移行が完了したら、適用を再度有効にしてください。

CHECK、トリガー、アプリケーション検証の比較

有効な範囲、許可される値、非負の数値、日付の順序といった、単純で自己完結したルールには CHECK を使用します。ルールが他のテーブルの照会を必要とする場合はトリガーを使用します。外部の状態(レート制限、利用可否の確認)に関わるルールにはアプリケーション検証を使用します。

よくある質問

CHECK 制約はすべてのストレージエンジンで動作しますか?

はい。一部の MySQL 機能とは異なり、CHECK 制約は InnoDB、MyISAM、およびその他のストレージエンジンで動作します。ただし、MyISAM テーブルでは構文的に有効な制約を定義できますが、このストレージエンジンにはロールバックがないため、MyISAM で制約が失敗すると部分的なデータが残ることがあります。InnoDB は完全なロールバックによって違反をクリーンに処理します。

CHECK 制約は他のテーブルを参照できますか?

いいえ。CHECK 式は、現在のテーブルの現在の行に限定されます。CHECK 式では、サブクエリ、ストアド関数、および他のテーブルへの参照は許可されません。テーブルをまたぐ検証にはトリガーを使用してください。

CHECK 制約は昔から MySQL にありましたか?

古い MySQL バージョンでも構文は受け入れられましたが、制約は黙って無視されていました。古いスキーマから移行する場合は、既存の CHECK 句が有効であり、適用したいルールを含んでいることを確認してください。

トラブルシューティング

関連項目