MySQL 检查约束

一、MySQL 检查约束 语法

检查约束是控制特定列中的值的完整性约束。它确保列中插入或更新的值必须与给定条件匹配。换句话说,它确定与列关联的值在给定条件下是否有效。

在 8.0.16 版本之前,MySQL 使用此约束的受限版本。在以前的版本中,我们可以创建此约束,但它不起作用。这意味着它的语法受支持但不适用于数据库。在早期版本中,CREATE TABLE 语句可以包含 CHECK 约束,但它们会被 MySQL 解析和忽略。我们可以在以前的版本中使用以下语法:

CHECK (expr)   

如果我们使用以前的版本并想使用检查约束,我们可以通过使用 WITH CHECK OPTION 视图或触发器来模拟它来使用约束。

在 8.0.16 版本之后,MySQL对所有存储引擎使用 CHECK 约束,即表约束和列约束:

[CONSTRAINT [symbol]] CHECK (expr) [[NOT] ENFORCED]  

在这种语法中,我们首先需要为要创建的检查约束编写名称。如果我们不写它,MySQL 会自动生成一个具有以下约定的名称:

table_name_chk_n  

这里,n表示数字,例如用户表的 CHECK 约束名称将是 user_chk_1、user_chk_2 等。接下来,我们需要为每个表记录指定一个布尔表达式,该表达式应该被评估为 TRUE 或 UNKNOWN。如果此表达式返回 FALSE,则对给定值发生约束冲突。

第三,我们可以选择使用强制子句来验证检查约束是否被强制执行。如果我们想创建和强制执行约束,请使用 ENFORCED 或 omit 子句。如果您想创建一个约束而不强制执行它,请使用 NOT ENFORCED 子句。

前面我们已经讨论过,CHECK 约束在 MySQL 中可以用作表约束或列约束。如果我们将 CHECK 约束指定为一个表,它可能适用于多个列。相反,如果我们为一个列定义了这个约束,它可以被引用到唯一定义它的列。

二、MySQL 检查约束 示例

让我们通过各种示例了解如何对列和表使用检查约束。

1) MySQL CHECK 约束与列

以下语句创建了一个名为vehicle的新表,我们在其中指定列的检查约束:

CREATE TABLE vehicle (  
    vehicle_no VARCHAR(18) PRIMARY KEY,  
    model_name VARCHAR(45),  
    cost_price DECIMAL(10,2 ) NOT NULL CHECK (cost_price >= 0),  
    sell_price DECIMAL(10,2) NOT NULL CHECK (sell_price >= 0)  
);  

在语句中,我们可以看到两个 CHECK 约束列,即cost_price和sell_price列。如前所述,如果我们没有明确指定检查约束名称,MySQL 会自动为它们命名。

我们可以使用SHOW CREATE TABLE语句来显示带有 CHECK 约束名称的表信息,如下所示:

mysql> SHOW CREATE TABLE vehicle;  

我们应该得到下面的输出,我们可以看到 MySQL 为检查约束生成了名为vehicle_chk_1和vehicle_chk_2的名称。

接下来,我们将使用以下语句将一些记录插入到表中:

mysql> INSERT INTO vehicle(vehicle_no, model_name, cost_price, sell_price)   
VALUES('S2001', 'Scorpio', 950000, 1000000),  
('M3000', 'Mercedes', 2500000, 3000000);  

该语句被正确执行,因为它不违反检查约束条件。每当我们在检查约束列中插入或更新导致布尔表达式的评估不正确的值时,MySQL 都会反对更改并给出错误消息。请参阅以下尝试将新记录插入车辆表的语句:

mysql> INSERT INTO vehicle(vehicle_no, model_name, cost_price, sell_price)   
VALUES('R0001', 'Rolls Royas', 75000000, -85000000);  

执行此语句后,MySQL 发出如下错误:

ERROR 3819 (HY000): Check constraint 'vehicle_chk_2' is violated.  

我们将收到此错误,因为 sell_price 值列是负数,通过将表达式price >= 0执行结果为false违反了检查约束规则。

2) MySQL CHECK 约束与表

首先,我们将使用以下语句删除上表:

mysql> DROP TABLE IF EXISTS vehicle;  

接下来,我们将使用以下语句再次创建相同的表名车辆,并添加一个检查约束:

CREATE TABLE vehicle (  
    vehicle_no VARCHAR(18) PRIMARY KEY,  
    model_name VARCHAR(45),  
    cost_price DECIMAL(10,2 ) NOT NULL CHECK (cost_price >= 0),  
    sell_price DECIMAL(10,2) NOT NULL CHECK (sell_price >= 0),  
    CONSTRAINT vehicle_chk_sp_gt_cp CHECK(sell_price > cost_price)  
);  

在这个语句中,我们可以看到一个新的子句,它定义了一个表 CHECK 约束以确保sell_price 总是高于 cost_price,如下所示:

CONSTRAINT vehicle_chk_sp_gt_cp CHECK(sell_price > cost_price)  

由于我们已经明确定义了检查约束的名称,MySQL 在表定义中添加了这个具有指定名称的新约束。我们可以再次使用 SHOW CREATE TABLE 语句来显示具有 CHECK 约束名称的表定义,如下所示:

在输出结果中,我们可以看到 MySQL 在列列表之后的表描述末尾生成了一个表的检查约束名称,如红色矩形框所示。

接下来,我们将向表中添加一些记录,如下所示:

mysql> INSERT INTO vehicle(vehicle_no, model_name, cost_price, sell_price)   
VALUES('S2001', 'Avenger', 250000, 275000),  
('M3000', 'Apache', 120000, 125000);  

该语句被正确执行,因为它不违反检查约束条件。同样,我们将尝试尝试将一条新记录插入到sell_price 小于 cost_price的表中:

INSERT INTO vehicle (vehicle_no, model_name, cost_price, sell_price)   
VALUES('R0001', 'Honda', 80000, 70000);  

由于违反约束,MySQL 拒绝更改并给出错误消息。请参阅以下输出:

三、如何删除检查约束?

我们可以使用以下语句从表或列中删除检查约束:

ALTER TABLE table_name DROP CHECK constraint_name;  

或者

ALTER TABLE table_name DROP CONSTRAINT constraint_name;  

例如,如果我们想从表车辆中删除检查约束,我们可以执行如下语句:

mysql> ALTER TABLE vehicle DROP CHECK vehicle_chk_sp_gt_cp; 

此语句删除指定的约束。经过验证,我们可以在输出中看到指定的约束名称已经被成功删除。

热门文章

优秀文章