Skip to main content

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

All examples in this guide work on VillageSQL. Install Now →
MySQL enforces CHECK constraints. The syntax was accepted in older versions but silently ignored — a behavior that surprised many developers migrating from PostgreSQL.

Defining CHECK Constraints

Add a CHECK constraint inline with the column or as a table-level constraint:
Or inline with the column definition:
Table-level constraints are necessary when the check expression spans multiple columns:

Enforcement

MySQL enforces CHECK constraints on INSERT and UPDATE. A violation returns ERROR 3819 (HY000): Check constraint 'name' is violated.:
The error message includes the constraint name, which is why naming constraints is worth the extra typing. CHECK constraints are not evaluated on DELETE. They’re also not re-evaluated when the constraint itself is added to an existing table — adding a constraint to a table with existing data that violates it will fail immediately.

Adding and Removing Constraints

Add a constraint to an existing table:
Drop a named constraint:
List all constraints on a table:

Disabling Enforcement

Disable a specific constraint without dropping it:
Re-enable it:
NOT ENFORCED is useful during data migrations when you need to temporarily bypass validation. Re-enable enforcement when the migration is complete.

CHECK vs Triggers vs Application Validation

Use CHECK for simple, self-contained rules: valid ranges, allowed values, non-negative numbers, date ordering. Use a trigger when the rule requires querying other tables. Use application validation for rules involving external state (rate limits, availability checks).

Frequently Asked Questions

Do CHECK constraints work on all storage engines?

Yes. Unlike some MySQL features, CHECK constraints work on InnoDB, MyISAM, and other storage engines. However, MyISAM tables can have defined constraints that are syntactically valid but this storage engine does not have rollback, so a failed constraint on MyISAM can leave partial data. InnoDB handles violations cleanly with full rollback.

Can CHECK constraints reference other tables?

No. CHECK expressions are limited to the current row of the current table. Subqueries, stored functions, and references to other tables are not allowed in CHECK expressions. Use a trigger for cross-table validation.

Were CHECK constraints always in MySQL?

The syntax was accepted in older MySQL versions, but constraints were silently ignored. If you’re migrating from an older schema, verify that existing CHECK clauses are valid and contain rules you want enforced.

Troubleshooting

See also