数据库检查约束(CHECK Constraint)是一种用于限制列中数据取值范围或格式的规则,它确保只有满足特定条件的值才能被插入或更新到表中,通过合理使用检查约束,可以有效维护数据的完整性和一致性,避免无效或错误的数据进入数据库,以下将详细介绍检查约束的写法、应用场景及注意事项。

检查约束的基本语法
在SQL中,创建检查约束通常使用ALTER TABLE或CREATE TABLE语句,以MySQL、PostgreSQL等主流数据库为例,基本语法如下:
ALTER TABLE 表名 ADD CONSTRAINT 约束名 CHECK (条件表达式);
或在建表时直接定义:
CREATE TABLE 表名 (
列名 数据类型,
CONSTRAINT 约束名 CHECK (条件表达式)
);
限制年龄列的值必须在18到60岁之间:
ALTER TABLE employees ADD CONSTRAINT chk_age CHECK (age >= 18 AND age <= 60);
条件表达式的常见用法
检查约束的条件表达式可以包含比较运算符(如, >, <)、逻辑运算符(如AND, OR, NOT)以及函数,以下是几种典型场景:

- 数值范围限制:如成绩列需在0到100之间:
CONSTRAINT chk_score CHECK (score BETWEEN 0 AND 100);
- 字符串格式验证:如邮箱列需包含符号:
CONSTRAINT chk_email CHECK (email LIKE '%@%.%');
- 枚举值限制:如性别列只能是“男”或“女”:
CONSTRAINT chk_gender CHECK (gender IN ('男', '女')); - 复杂逻辑组合:如账户余额不能为负且透支额度有限:
CONSTRAINT chk_balance CHECK (balance >= 0 OR balance >= -overdraft_limit);
多列与命名规范
检查约束可以基于单列或多列条件,确保订单的结束时间不早于开始时间:
ALTER TABLE orders ADD CONSTRAINT chk_time CHECK (end_time >= start_time);
约束命名建议使用chk_前缀加上列名或功能描述(如chk_age_range),便于后期维护,若未指定约束名,数据库会自动生成(如constraint1),但显式命名更清晰。
注意事项
- 性能影响:检查约束会在每次数据修改时触发验证,高频操作或复杂条件可能影响性能,需权衡业务需求。
- 数据库兼容性:不同数据库对检查约束的支持略有差异,例如SQLite在旧版本中不支持,而SQL Server、Oracle等均支持。
- 默认值与NULL值:检查约束不适用于
NULL值(除非显式包含IS NULL条件),因为NULL会被视为“未知”而非“不满足条件”。 - 修改与删除:若需修改约束,需先删除后重建:
ALTER TABLE 表名 DROP CONSTRAINT 约束名; ALTER TABLE 表名 ADD CONSTRAINT 约束名 CHECK (新条件);
应用场景示例
在电商系统中,商品表的价格需满足“非负且促销价不高于原价”的规则:
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(100),
original_price DECIMAL(10, 2),
sale_price DECIMAL(10, 2),
CONSTRAINT chk_price CHECK (
original_price >= 0
AND sale_price >= 0
AND sale_price <= original_price
)
);
相关问答FAQs
Q1: 检查约束与触发器(Trigger)有何区别?
A1: 检查约束是数据库自动执行的轻量级规则,适用于简单的列或表级条件验证,性能较高;触发器则可执行更复杂的逻辑(如跨表操作、调用外部程序),但开发成本高且可能影响性能,优先使用检查约束,仅在需要灵活逻辑时选择触发器。

Q2: 如何在已有表中添加检查约束并处理历史数据?
A2: 使用ALTER TABLE添加约束时,若表中已有违反约束的数据,操作会失败,需先清理无效数据(如更新或删除),或暂时禁用约束(部分数据库支持,如SQL Server的NOCHECK选项)。
-- SQL Server中先禁用约束再添加 ALTER TABLE 表名 NOCHECK CONSTRAINT 约束名; ALTER TABLE 表名 ADD CONSTRAINT 约束名 CHECK (条件);