MySQL/MariaDB视图详解

视图是表表达式的一种,所以它也是虚拟表。对视图操作的时候会通过语句动态的从表中临时获取数据。

1.创建、修改视图
CREATE [OR REPLACE]
    [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
    VIEW [IF NOT EXISTS] view_name [(column_list)]
    AS select_statement
    [WITH [CASCADED | LOCAL] CHECK OPTION]

ALTER
    [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
    VIEW view_name [(column_list)]
    AS select_statement
    [WITH [CASCADED | LOCAL] CHECK OPTION]

当使用or replace时,如果视图存在则此语句相当于alter view,如果视图不存在,则等价于create view。

关于algorithm,后文详细说明。

with [local|cascaded] check option:它的对象是可更新视图(即merge算法的视图)。对于可更新视图,可给定WITH CHECK OPTION子句来防止插入或更新非法记录,除非作用在行上的select_statement中的WHERE子句为"true"。其中local表示只要满足本视图的筛选条件即可插入或更新,cascaded表示必须满足所有视图的筛选条件才可插入或更新。默认是with cascaded check option。

例如,下面的语句定义了3个视图,其中后两个视图是以第一个视图作为基表创建的。在向view2和view3插入记录的时候,如果记录中字段a=10:由于view2默认使用的是cascaded选项,a=10不满足view1的条件,所以插入失败;而view3使用的是local选项,只需满足view3的条件即可,所以a=10满足条件,即可以成功插入。
create view view1 as select * from t where a<10;
create view view2 as select * from view1 where a>5;
create view view3 as select * from view1 where a>5 with local check option;

MySQL/MariaDB中视图创建后,列的定义是"已固化"状态。也就是说,如果视图定义语句中的select语句中使用了星号"*"表示所有列,在创建视图的时候会转化为对应的列名存储在视图定义语句中,所以如果基表中新增了列将不会被视图的SQL语句检索到。

例如:
create or replace view v_city
as
select * from world.city where id>200;


查看视图的定义语句:可以看到,select语句中的星号是替换为了对应的列名来表示的。
mysql> mysql> show create view v_city\G
*************************** 1. row ***************************
                View: v_city
        Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`192.168.100.%` SQL SECURITY DEFINER VIEW `v_city` AS select `city`.`ID` AS `ID`,`city`.`Name` AS `Name`,`city`.`CountryCode` AS `CountryCode`,`city`.`District` AS `District`,`city`.`Population` AS `Population` from `city` where (`city`.`ID` > 200)
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)


在MySQL/MariaDB中视图定义语句中的select部分中,from后面不能是子查询。在这一点上MySQL/MariaDB和其他类型的数据库有些不一样。如果在某种条件下,视图的定义语句from字句正好需要的是子查询,可以将这个子查询先定义成视图,再将视图放在from字句中。 更新视图时,实际上是转到对应的基表上进行更新。

2.视图算法merge、temptable

algorithm={undefined|merge|temptable}是视图选择算法。视图的算法会影响MySQL/MariaDB处理视图的方式:
1.merge会将引用视图的语句与视图定义语句合并起来,使得视图定义的某一部分取代语句的对应部分。例如在引用视图时会将视图名替换成基表名,将查询涉及的列替换成基表中的列名等。
2.temptable将视图的结果放入临时表中,然后使用该表的数据执行对应语句操作。
3.undefined是让MySQL/MariaDB自己选择merge还是temptable,它更倾向于merge。这是未指定algorithm时的默认值。

例如,以下是merge的一个特殊例子,很能说明merge算法:
MariaDB [test]> create or replace table t
                (id int auto_increment,
                name char(20),
                age int,
                primary key(id));
MariaDB [test]> insert into t(name,age) values
    ('chenyi',21),
    ('huanger',22),
    ('zhangsan',23),
    ('lisi',24),
    ('wangwu',25),
    ('zhaoliu',26);
MariaDB [test]> select * from t;
+----+----------+------+
| id | name    | age  |
+----+----------+------+
|  1 | chenyi  |  21 |
|  2 | huanger  |  22 |
|  3 | zhangsan |  23 |
|  4 | lisi    |  24 |
|  5 | wangwu  |  25 |
|  6 | zhaoliu  |  26 |
+----+----------+------+
# 创建一个id<5的视图my_view
MariaDB [test]> create or replace algorithm=merge view my_view(vf1,vf2) as
                select id,name from t where age<24;
MariaDB [test]> select * from my_view;
+-----+----------+
| vf1 | vf2      |
+-----+----------+
|  1 | chenyi  |
|  2 | huanger  |
|  3 | zhangsan |
+-----+----------+

返回的结果是3行记录。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/19be6ad8e4ca0ce7829d479b76ff9ad6.html