CHECK 限制其实就像你表门口的保安,保证你往表里加的数据都得满足某些条件。如果你想塞进一些不合规的数据,数据库会直接拒绝你。
想象一下,你想在德国开个商店。但法律规定星期天是休息日,这天不能营业。这个限制就像数据库里的 CHECK。你试图设置商店营业时间:一周七天都开门,系统立马回你:"Nein, nein,星期天不行,这样的时间表过不了审核!"
数据库也是一样:如果你设置的值违反了 CHECK 规则,系统就会拦住你,防止你的数据出现“逻辑错误”。
为什么要用 CHECK?
- 保证数据质量:
CHECK能防止不合逻辑或者错误的数据混进表里。 - 减少出错概率: 你不用手动检查数据再插入,可以直接交给数据库搞定。
- 逻辑自带: 校验规则直接写在数据库结构里,不用靠应用层代码来兜底。
CHECK 怎么用?
CHECK 限制可以在建表的时候加,也可以后面用 ALTER TABLE 命令补上。基本语法如下:
CREATE TABLE 表名 (
列名 数据类型 CHECK (条件)
);
条件 就是一个逻辑表达式,每个该列的值都得满足。如果不满足,数据库就会报错。
例子1:检查数值范围
比如我们建个 students 表,要求学生的年龄(age)只能在16到100之间:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INTEGER CHECK (age >= 16 AND age <= 100)
);
现在,如果你想插入一个12岁的学生,数据库会立马“抓你小辫子”:
INSERT INTO students (name, age)
VALUES ('Maria Chi', 12);
错误:
ERROR: new row for relation "students" violates check constraint "students_age_check"
DETAIL: Failing row contains (1, Maria Chi, 12).
没错,数据库就是这么严格。没满16岁,别想混进去。
例子2:检查数据格式
假设我们有个 emails 表,存邮箱地址。我们想确保邮箱里一定有 @ 符号(简单点的校验方式):
CREATE TABLE emails (
id SERIAL PRIMARY KEY,
email VARCHAR(255) CHECK (email LIKE '%@%')
);
试着加一个不合规的邮箱地址:
INSERT INTO emails (email)
VALUES ('notanemail.com');
错误:
ERROR: new row for relation "emails" violates check constraint "emails_email_check"
DETAIL: Failing row contains (1, notanemail.com).
只要所有数据都带 @,就不会报错:
INSERT INTO emails (email)
VALUES ('example@student.com');
这条语句就能顺利执行。
例子3:多列条件校验
CHECK 限制不仅能校验单列,还能写多列相关的逻辑表达式。比如我们有个 employees 表,要求工资(salary)必须大于奖金(bonus):
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
salary NUMERIC CHECK (salary > 0),
bonus NUMERIC CHECK (bonus >= 0),
CHECK (salary > bonus)
);
现在,如果有人想加个奖金比工资还高的员工,数据库绝对不让你过:
INSERT INTO employees (name, salary, bonus)
VALUES ('Otto Lin', 3000, 4000);
错误:
ERROR: new row for relation "employees" violates check constraint "employees_salary_bonus_check"
DETAIL: Failing row contains (1, Otto Lin, 3000, 4000).
实际应用场景
CHECK 限制特别适合你的业务逻辑和数据限制关系很紧的时候。比如:
- 电商平台: 禁止加负价格的商品。
- 在线教育平台: 校验学员年龄。
- 医疗系统: 确保病人体温在合理范围内。
这些校验不仅是安全层,还能帮开发者和用户省不少麻烦和时间。
注意事项和常见坑
用 CHECK 的时候,记住这些点:
CHECK里的逻辑表达式对表里所有行都得成立。如果有哪一行不满足,想加限制前得先修正那行。如果插入的值是
NULL,CHECK不会校验。也就是说,CHECK (age >= 18)对age = NULL不会报错。因为只要表达式里有NULL,结果就是未知。如果你想禁止NULL,记得加NOT NULL。CHECK里条件太复杂的话,大表插入和更新数据时性能会受影响。
GO TO FULL VERSION