定义

当使用 WITH CHECK OPTION 子句创建视图时,MySQL会通过视图检查正在更改的每个行,例如 插入,更新,删除,以使其符合视图的定义。

MySQL允许基于另一个视图创建视图,它还会检查依赖视图中的规则以保持一致性。为了确定检查的范围,mysql提供了两个选项:CASCADED 和 LOCAL ,默认值为 CASCADED 。

检查选项的关键字是检查,即检查操作记录的时候,是否符合视图的定义?如果符合则执行成功,不符合则执行失败。

例子

User 表

为了举例说明,我们先创建一个用户表(user),创建用户表的语句如下:

CREATE TABLE `user` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
    `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `age` INT(11) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`) USING BTREE
)

再往里面添加一些数据:
user.png

定义视图

先定义一个不带检查选项的视图,查询年龄大于等于 18 的用户:

ALTER ALGORITHM = UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `user_age_gte_18` AS select `user`.`id` AS `id`,`user`.`name` AS `name`,`user`.`created_at` AS `created_at`,`user`.`updated_at` AS `updated_at`,`user`.`age` AS `age` from `user` where (`user`.`age` >= 18) ;

view_user_age_gte_18.png

数据:
data_user_age_gte_18.png

我们向 user_age_gte_18 的视图里面添加两条数据,一条年龄小于 18 的数据,一条大于 18 岁的数据:

  • name: 东方,age: 17;
  • name: 维德,age: 21;

向视图 user_age_gte_18 添加数据的语句:

INSERT INTO user_age_gte_18(`name`,`age`) VALUES ('东方', 17); 
INSERT INTO user_age_gte_18(`name`,`age`) VALUES ('维德', 21); 

查看 user 表:
add_data_to_user_age_gte_18.png

可以看出,我们成功地向 user 表中添加了这两条数据,但是感觉存在矛盾:我们定义的视图 user_age_gte_18 是用于查询年龄大于等于 18 的用户,但是现在却能成功地添加 17 岁的东方

想要避免这种情况,可以使用检查选项

使用检查选项

语法:

CREATE [OR REPLACE] VIEW 视图名称[(列名列表)] AS SELECT语句 [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]

我们在 user_age_gte_18 视图的基础上加上检查选项,即在创建 user_age_gte_18 视图语句的末尾加上 WITH CHECK OPTION

MySQL 提供了两个选项:CASCADEDLOCAL ,默认值为 CASCADED。如果视图是基于表创建的,这两个选项就没什么区别。而 user_age_gte_18 视图依赖于 user 表,所以使用 CASCADEDLOCAL 区别不大,就用 CASCADED 来举例说明,它们之间的差异会起另外一篇博客来说明:

ALTER ALGORITHM = UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `user_age_gte_18` AS select `user`.`id` AS `id`,`user`.`name` AS `name`,`user`.`created_at` AS `created_at`,`user`.`updated_at` AS `updated_at`,`user`.`age` AS `age` from `user` where (`user`.`age` >= 18) WITH CASCADED CHECK OPTION;

user_age_gte_18_cascaded.png

我们再向 user_age_gte_18 的视图里面添加两条数据:

  • name: 艾AA,age: 15;
  • name: 智子,age: 23;

向视图 user_age_gte_18 添加数据的语句:

INSERT INTO user_age_gte_18(`name`,`age`) VALUES ('艾AA', 15); 
INSERT INTO user_age_gte_18(`name`,`age`) VALUES ('智子', 23); 

查看 user 表:
data_user_age_gte_18_cascaded.png

从表中可以看出,使用了检查选项后,只有 23 岁的智子成功地添加到了 user 表中。因为艾AA的年龄小于 18 岁,所以没有被添加到 user 表中,这样就更符合 user_age_gte_18 视图的定义

参考

  1. MySQL 视图——检查选项(cascaded、local)

Moonshadow2333
28 声望0 粉丝

征途漫漫