MySQL的检查约束(Check),其实什么用也没有

983 阅读2分钟

一、检查约束简介

在标准SQL中,检查约束(CHECK)可以通过 CREATE TABLE 或 ALTER TABLE 语句实现,根据用户实际的完整性要求来定义。例如限定某一列必须大于10小于20,限定某一列只能为A、B两个选项等。它可以分别对列或表实施 CHECK 约束。

虽然MySQL中也支持CHECK子句,但是却没有实际作用,完全不生效。

官方文档内容如下:

CHECK子句会被分析,但是会被忽略。请参见13.1.5节,“CREATE TABLE语法”。接受这些子句但又忽略子句的原因是为了提高兼容性,以便更容易地从其它SQL服务器中导入代码,并运行应用程序,创建带参考数据的表。请参见1.8.5节,“MySQL与标准SQL的差别”。

二、选取设置检查约束的字段

检查约束使用 CHECK 关键字,具体的语法格式如下:

CHECK <表达式>

其中: <表达式> 指的就是 SQL 表达式,用于指定需要检查的限定条件。

若将 CHECK 约束子句置于表中某个列的定义之后,则这种约束也称为基于列的 CHECK 约束。

在更新表数据的时候,系统会检查更新后的数据行是否满足 CHECK 约束中的限定条件。MySQL 可以使用简单的表达式来实现 CHECK 约束,也允许使用复杂的表达式作为限定条件,例如在限定条件中加入子查询。

注意:若将 CHECK 约束子句置于所有列的定义以及主键约束和外键定义之后,则这种约束也称为基于表的 CHECK 约束。该约束可以同时对表中多个列设置限定条件。

三、在创建表时设置检查约束

创建表时设置检查约束的语法规则如下:CHECK(<检查约束>)

示例1,在 demo_db 数据库中创建 demo_employee数据表,要求 salary 字段值大于 0 且小于 等于100,验证过程如下。

drop table if exists demo_employee;
create table if not exists demo_employee(
	id int(11) primary key,
	name varchar(22) UNIQUE,
	dept_id int(11),
	salary float,
	check(salary>0 and salary <=100)
);

-- 插入成功
insert into demo_employee values (1,'尹洪亮',1,50);
-- 居然也插入成功了,问什么会这样?请看下方的注意事项
insert into demo_employee values (2,'尹洪亮2',1,101);

注意事项:CHECK子句会被分析,但是会被忽略。接受这些子句但又忽略子句的原因是为了提高兼容性,以便更容易地从其它SQL服务器中导入代码。

四、在修改表时添加检查约束

修改表时设置检查约束的语法规则如下:

ALTER TABLE <数据表名> ADD CONSTRAINT <检查约束名> CHECK(<检查约束>)

实例2,修改 demo_employee数据表,要求 dept_id字段值小于 10。

-- 添加约束dept_id字段必须小宇10
alter table demo_employee add CONSTRAINT check_dept_id check (dept_id<10);
-- 插入dept_id=10,居然成功了,原因相同
insert into demo_employee values (3,'尹洪亮3',11,10);

五、删除检查约束

修改表时删除检查约束的语法规则如下:

ALTER TABLE <数据表名> DROP CONSTRAINT <检查约束名>;

实例3,删除check_dept_id这个约束

-- 这个语句会执行出错,因为check_dept_id这个约束根本就没有创建,mysql自动忽略了
ALTER TABLE demo_employee DROP CONSTRAINT check_dept_id;