摘要:在本教程中,您将了解WITH CHECK OPTION
子句中LOCAL
和CASCADED
之间的区别。
请注意,在继续本教程之前,您应该熟悉WITH CHECK OPTION
子句。如果不是这种情况,您可以按照WITH CHECK OPTION
教程进行操作。
LOCAL
& CASCADED
检查范围简介
当您使用WITH CHECK OPTION
子句创建视图并对视图发出DML语句(例如INSERT
、 UPDATE
和DELETE
)时,MySQL会检查以确保正在更改的行符合视图的定义。
由于视图可以基于其他视图创建,因此MySQL还会检查依赖视图中的规则以确保数据一致性。
为了确定检查的范围,MySQL 提供了两个选项: LOCAL
和CASCADED
。如果没有在WITH CHECK OPTION
子句中显式指定关键字,MySQL默认使用CASCADED
。
MySQL WITH CASCADED CHECK OPTION
请考虑以下示例以了解WITH CASCADED CHECK OPTION
的效果:
首先,创建一个名为t1
的表,其中有一列c
,其数据类型为整数。
CREATE TABLE t1 (
c INT
);
Code language: SQL (Structured Query Language) (sql)
接下来,根据t1
表创建视图v1
,其中c
列数据大于10。
CREATE OR REPLACE VIEW v1
AS
SELECT
c
FROM
t1
WHERE
c > 10;
Code language: SQL (Structured Query Language) (sql)
因为我们没有指定WITH CHECK OPTION
,所以下面的语句即使不符合v1
视图的定义也能工作。
INSERT INTO v1(c)
VALUES (5);
Code language: SQL (Structured Query Language) (sql)
然后,使用WITH CASCADED CHECK OPTION
子句基于v1
视图创建视图v2
。
CREATE OR REPLACE VIEW v2
AS
SELECT c FROM v1
WITH CASCADED CHECK OPTION;
Code language: SQL (Structured Query Language) (sql)
现在,通过v2
视图将一行值为 5 的行插入到t1
表中。
INSERT INTO v2(c)
VALUES (5);
Code language: SQL (Structured Query Language) (sql)
MySQL 发出以下错误消息:
Error Code: 1369. CHECK OPTION failed 'classicmodels.v2'
Code language: SQL (Structured Query Language) (sql)
它使不符合v2
视图定义的新行失败。
之后,基于v2
创建一个名为v3
的新视图。
CREATE OR REPLACE VIEW v3
AS
SELECT c
FROM v2
WHERE c < 20;
Code language: SQL (Structured Query Language) (sql)
通过v3
视图将新行插入到t1
表中,值为 8。
INSERT INTO v3(c)
VALUES (8);
Code language: SQL (Structured Query Language) (sql)
MySQL 发出以下错误消息:
Error Code: 1369. CHECK OPTION failed 'classicmodels.v3'
Code language: SQL (Structured Query Language) (sql)
即使该行看起来符合v3
视图的定义,插入语句也会失败。
因为视图v3
依赖于v2
视图,而v2
视图有WITH CASCADED CHECK OPTION
选项。
但是,以下插入语句有效。
INSERT INTO v3(c) VALUES (30);
Code language: SQL (Structured Query Language) (sql)
因为v3视图没有WITH CHECK OPTION
,并且该语句符合v2视图的定义。
总之,当视图使用WITH CASCADED CHECK OPTION
时,MySQL会递归地检查视图的规则以及底层视图的规则。
WITH LOCAL CHECK OPTION
MySQL
让我们使用上面WITH LOCAL CHECK OPTION
相同的示例来查看差异。
首先,更改v2
视图以使用WITH LOCAL CHECK OPTION
。
ALTER VIEW v2 AS
SELECT
c
FROM
v1
WITH LOCAL CHECK OPTION;
Code language: SQL (Structured Query Language) (sql)
其次,插入与上例相同的行。
INSERT INTO v2(c)
VALUES (5);
Code language: SQL (Structured Query Language) (sql)
它成功了。
因为v2
视图没有任何规则。视图v2
依赖于v1
视图。但是, v1
视图没有指定检查选项,因此,MySQL会跳过检查v1
视图中的规则。
请注意,此语句在使用WITH CASCADED CHECK OPTION
创建的 v2 视图中失败。
第三,通过v3视图将同一行插入到t1表中。
INSERT INTO v3(c) VALUES (8);
Code language: SQL (Structured Query Language) (sql)
本例成功是因为由于v2视图的WITH LOCAL CHECK OPTION
MySQL没有检查v1视图的规则。
另请注意,此语句在 v2 使用WITH CASCADED CHECK OPTION
创建的示例中失败。
因此,如果视图使用WITH LOCAL CHECK OPTION
,MySQL将检查具有WITH LOCAL CHECK OPTION
和WITH CASCADED CHECK OPTION
的视图的规则。
与使用WITH CASCADED CHECK OPTION
视图不同的是,MySQL检查所有依赖视图的规则。
请注意,在MySQL 5.7.6之前,如果您使用带有WITH LOCAL CHECK OPTION
视图,MySQL仅检查当前视图的规则,而不会检查基础视图的规则。