
在 MySQL 中,CHECK 约束用于限制某列中可以插入的值的范围,确保数据满足特定条件。然而需要注意的是,在 MySQL 8.0 及更早版本中,虽然支持 CHECK 约束的语法,但目前并不会真正强制执行检查(即语法上允许定义,但不会生效)。这意味着即使你设置了 CHECK,MySQL 也不会阻止不符合条件的数据插入。
1. CHECK 约束的基本语法
尽管不强制执行,但你可以按照标准 SQL 语法添加 CHECK 约束:
示例:创建一个学生表,限制年龄必须大于等于 18
CREATE TABLE students ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), age INT, CONSTRAINT chk_age CHECK (age >= 18) );
这条语句在语法上是正确的,也能成功执行。但如果你尝试插入 age = 16 的记录,MySQL 不会报错,数据仍会被插入。
2. 验证 CHECK 是否生效
你可以通过以下方式测试 CHECK 是否起作用:
INSERT INTO students (name, age) VALUES ('张三', 16); SELECT * FROM students;
你会发现 age = 16 的数据被成功插入,说明 CHECK 并未实际限制。
3. 替代方案:使用触发器模拟 CHECK
由于 CHECK 不生效,推荐使用触发器(TRIGGER)来实现类似功能:
DELIMITER $$ CREATE TRIGGER check_age_before_insert BEFORE INSERT ON students FOR EACH ROW BEGIN IF NEW.age < 18 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '年龄不能小于 18'; END IF; END$$ <p>CREATE TRIGGER check_age_before_update BEFORE UPDATE ON students FOR EACH ROW BEGIN IF NEW.age < 18 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '年龄不能小于 18'; END IF; END$$ DELIMITER ;</p>
这样在插入或更新时,如果 age 小于 18,就会抛出错误,阻止操作。
4. 注意事项与建议
- MySQL 目前对 CHECK 的支持是“解析但忽略”,主要是为了兼容 SQL 标准语法。
- 如果你依赖数据完整性,不要仅靠 CHECK,应结合应用层校验或数据库触发器。
- 其他数据库如 postgresql、SQL Server 会真正执行 CHECK 约束,迁移时需注意差异。
- 查看表结构时,SHOW CREATE TABLE 会显示 CHECK 定义,但这不代表它在运行。
基本上就这些。虽然 MySQL 写起来支持 CHECK,但真要控制数据合法性,还得靠触发器或程序逻辑来兜底。