VillageSQL is a drop-in replacement for MySQL with extensions.
All examples in this guide work on VillageSQL. Install Now →
CHECK constraints. Before that version, MySQL accepted the syntax but silently ignored it — a behavior that surprised many developers migrating from PostgreSQL.
Defining CHECK Constraints
Add aCHECK constraint inline with the column or as a table-level constraint:
Enforcement
MySQL enforcesCHECK constraints on INSERT and UPDATE. A violation returns ERROR 3819 (HY000): Check constraint 'name' is violated.:
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:Disabling Enforcement
Disable a specific constraint without dropping 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
| CHECK constraint | Trigger | Application code | |
|---|---|---|---|
| Enforced by | MySQL (always) | MySQL (always) | Application (only when app runs) |
| Performance | Very low overhead | Per-row execution overhead | Round-trip cost |
| Error visibility | SQL error with constraint name | SIGNAL required to surface error | Application-defined |
| Cross-column checks | Yes | Yes | Yes |
| Cross-table checks | No | Yes (can query other tables) | Yes |
| Complexity | Simple expressions only | Arbitrary SQL logic | Arbitrary code |
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 starting in MySQL 3.23, but constraints were silently ignored until MySQL 8.0.16. Code written before 8.0.16 may includeCHECK clauses that did nothing. If you’re migrating from a pre-8.0.16 schema, verify that existing CHECK clauses are actually valid and contain rules you want enforced.
Troubleshooting
| Problem | Solution |
|---|---|
ERROR 3819: Check constraint violated | The INSERT or UPDATE value fails the constraint — check the constraint name in the error to identify which rule was violated |
ALTER TABLE ADD CONSTRAINT fails immediately | Existing rows in the table violate the constraint — fix the data first or use NOT ENFORCED during migration |
| CHECK constraint defined but not being enforced | MySQL version is below 8.0.16 — upgrade or use triggers for enforcement |
| Cannot drop a constraint | Use the constraint name (not the column name) with DROP CHECK or DROP CONSTRAINT |
| Constraint name unknown | Query information_schema.check_constraints to find constraint names for the table |

