OceanBase 数据库何时执行约束检查(Checking of Constraint),有助于明确存在各种约束时允许执行的操作类型。
如下图所示,定义 emp 表。在 emp 表上定义自引用约束(Self-Referential Constraint),mgr 列的值依赖于 empno 列的值。为了简化示例,以下内容只针对 emp 表的 empno(employee_id)以及 mgr(manager_id)列。

现在向 emp 表插入第一条数据。由于此时表内没有数据,mgr 列无法引用 empno 列已有的值,可以根据如下场景执行数据插入:
如果
mgr列上没有定义NOT NULL约束,可以在第一行的mgr列上输入一个空值。由于外键约束允许空值,所以此行能成功插入表中。可以向第一行的
empno及mgr列输入一个相同的值。此种情况说明是在语句运行完成后执行的约束检查(Constraint Checking)。如果在第一行的父键(Parent Key)及外键(Foreign Key)插入相同的值,必须首先运行语句(即插入数据行),再检查此行数据的mgr列值是否能与此表内的某个empno列值相匹配。执行一个多行的
INSERT语句,例如与SELECT语句结合的INSERT语句,将插入存在相互引用关系的多行数据。例如,第一行的empno列值为 200,mgr列值为 300,而第二行的empno列值为 300,mgr列值为 200。
此种情况也说明数据库会将约束检查延迟直至语句运行结束。所有数据行首先被插入,之后逐行检查是否存在违反约束的情况。
用上述的自引用约束再举一个例子。假设公司被收购,所有员工编号需要被更新为当前值加 5000,以便和新公司的员工编号保持一致。由于经理编号也是员工编号,所以此值也需要加 5000。下图为被更新之前的 emp 表,其中包含 empno 与 mgr 两列。empno 列有 3 个值:210、211 和 212。mgr 列有两个值:210 和 211。

对 emp 表执行以下 SQL:
UPDATE EMP
SET empno = empno + 5000,
mgr = mgr + 5000;
尽管 emp 表上定义的约束要求每个 mgr 值必须能和一个 empno 值相匹配,此语句仍旧可以执行,因为在语句执行后才进行约束检查。下图表明执行了 SQL 语句的全部操作之后才进行约束检查。

首先为每个员工编号加 5000,再为每个经理编号加 5000。在第一步中,empno 列的值 210 被更新为 5210。在第二步中,empno 列的值 211 被更新为 5211,mgr 列的值 210 被更新为 5210。在第三步中,empno 列的值 212 被更新为 5212,mgr 列的值 211 被更新为 5211。最后执行约束检查。
上述示例说明了 INSERT 和 UPDATE 语句的约束检查机制。事实上各类 DML 语句的约束检查机制均相同,这些 DML 语句包括 UPDATE、INSERT 以及 DELETE 等语句。OceanBase 数据库何时执行约束检查(Checking of Constraint),有助于明确存在各种约束时允许执行的操作类型。
如下图所示,定义 emp 表。在 emp 表上定义自引用约束(Self-Referential Constraint),mgr 列的值依赖于 empno 列的值。为了简化示例,以下内容只针对 emp 表的 empno(employee_id)以及 mgr(manager_id)列。
现在向 emp 表插入第一条数据。由于此时表内没有数据,mgr 列无法引用 empno 列已有的值,可以根据如下场景执行数据插入:
如果
mgr列上没有定义NOT NULL约束,可以在第一行的mgr列上输入一个空值。由于外键约束允许空值,所以此行能成功插入表中。可以向第一行的
empno及mgr列输入一个相同的值。此种情况说明是在语句运行完成后执行的约束检查(Constraint Checking)。如果在第一行的父键(Parent Key)及外键(Foreign Key)插入相同的值,必须首先运行语句(即插入数据行),再检查此行数据的mgr列值是否能与此表内的某个empno列值相匹配。执行一个多行的
INSERT语句,例如与SELECT语句结合的INSERT语句,将插入存在相互引用关系的多行数据。例如,第一行的empno列值为 200,mgr列值为 300,而第二行的empno列值为 300,mgr列值为 200。
此种情况也说明数据库会将约束检查延迟直至语句运行结束。所有数据行首先被插入,之后逐行检查是否存在违反约束的情况。
用上述的自引用约束再举一个例子。假设公司被收购,所有员工编号需要被更新为当前值加 5000,以便和新公司的员工编号保持一致。由于经理编号也是员工编号,所以此值也需要加 5000。下图为被更新之前的 emp 表,其中包含 empno 与 mgr 两列。empno 列有 3 个值:210、211 和 212。mgr 列有两个值:210 和 211。
对 emp 表执行以下 SQL:
UPDATE EMP
SET empno = empno + 5000,
mgr = mgr + 5000;
尽管 emp 表上定义的约束要求每个 mgr 值必须能和一个 empno 值相匹配,此语句仍旧可以执行,因为在语句执行后才进行约束检查。下图表明执行了 SQL 语句的全部操作之后才进行约束检查。
首先为每个员工编号加 5000,再为每个经理编号加 5000。在第一步中,empno 列的值 210 被更新为 5210。在第二步中,empno 列的值 211 被更新为 5211,mgr 列的值 210 被更新为 5210。在第三步中,empno 列的值 212 被更新为 5212,mgr 列的值 211 被更新为 5211。最后执行约束检查。
上述示例说明了 INSERT 和 UPDATE 语句的约束检查机制。事实上各类 DML 语句的约束检查机制均相同,这些 DML 语句包括 UPDATE、INSERT 以及 DELETE 等语句。




