MySQL CHECK CONSTRAINT

17 Mar 2025 | 5 分钟阅读

CHECK 约束是一种完整性约束,用于控制特定列的值。它确保列中插入或更新的值必须与给定的条件匹配。换句话说,它**根据给定的条件确定与列关联的值是否有效**。

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

如果使用早期版本并希望使用 check 约束,则可以通过使用带有 CHECK OPTION 的视图或触发器来模拟约束。

在 8.0.16 版本之后,MySQL 将 CHECK 约束用于所有存储引擎,即表约束和列约束。

在此语法中,我们首先需要为要创建的 check 约束写一个名称。如果我们不写,MySQL 将按照以下约定自动生成一个名称:

在这里,**n** 表示数字,例如用户表的 CHECK 约束名称将是 user_chk_1、user_chk_2,依此类推。接下来,我们需要指定一个**布尔表达式**,对于每个表记录,该表达式都必须评估为 TRUE 或 UNKNOWN。如果此表达式返回 FALSE,则会导致给定值的约束冲突。

第三,我们可以选择性地使用 enforcement clause 来验证 check 约束是否已强制执行。如果我们希望创建并强制执行约束,请使用 ENFORCED 或省略该子句。如果我们希望在不强制执行约束的情况下创建约束,请使用 NOT ENFORCED 子句。

我们已经讨论过,CHECK 约束可以在 MySQL 中用作表约束或列约束。如果我们将 CHECK 约束指定为表约束,则它可以应用于多个列。相比之下,如果我们为列定义了此约束,则只能引用它所定义的列。

MySQL CHECK 约束示例

让我们通过各种示例来了解如何使用列和表的 check 约束。

1) MySQL 列 CHECK 约束

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

在此语句中,我们可以看到**两个 CHECK 约束列**,分别是 **cost_price** 和 **sell_price** 列。如前所述,如果我们不显式指定 check 约束的名称,MySQL 会自动为其命名。

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

我们应该得到以下输出,其中我们可以看到 MySQL 为 check 约束生成的名称是 **vehicle_chk_1** 和 **vehicle_chk_2**。

MySQL CHECK CONSTRAINT

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

此语句执行正确,因为它不违反 check 约束条件。每当我们在 check 约束列中插入或更新一个值,导致布尔表达式的评估不正确时,MySQL 都会拒绝更改并显示错误消息。请参阅以下尝试将新记录插入 vehicle 表的语句:

执行此语句后,**MySQL 会发出以下错误**:


MySQL CHECK CONSTRAINT

我们将收到此错误,因为 sell_price 列的值为负数,这违反了 check 约束规则,将表达式 **price >= 0** 评估为 **FALSE**。

2) MySQL 表 CHECK 约束

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

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

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

由于我们已显式定义了 check 约束的名称,MySQL 会将此新约束添加到具有指定名称的表中。我们可以再次使用 SHOW CREATE TABLE 语句来显示带有 CHECK 约束名称的表定义,如下所示:

MySQL CHECK CONSTRAINT

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

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

此语句执行正确,因为它不违反 check 约束条件。再次,我们将尝试向表中插入一条新记录,其中 **sell_price 小于 cost_price**:

由于约束冲突,MySQL 会拒绝更改并显示错误消息。请参阅以下输出:

MySQL CHECK CONSTRAINT

如何删除 check 约束?

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

例如,如果我们想从 vehicle 表中删除 check 约束,可以执行以下语句:

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

MySQL CHECK CONSTRAINT