作者:老王
MySQL中
视图的语法是这样的:
CREATE
[OR REPLACE]
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = { user | CURRENT_USER }]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
视图对程序会产生一定的影响:
比如,以前我们会直接在数据库表上进行CRUD操作,但是这种做法相当“硬”,之所以这么说,是因为一旦数据库发生某种变化,比如说字段改名,对程序代码的影响是很大的。有了视图以后,每当建立一个新的数据库表之后,我们可以原封不动的建立一个新的数据库视图,CRUD操作均在此视图上完成,避免直接操作数据库表,如此一来,视图成为了表的facade,变化可以在视图里完成平滑的过渡,从而避免了对程序的影响。
如果你没太看懂我上面的话,不妨跟着我下面的步骤实战一下:
我们的系统有一个文章表:
CREATE TABLE article_table (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
title VARCHAR(255) NOT NULL ,
content TEXT NOT NULL
)
我们原封不动映射了一个视图:
CREATE VIEW article_view AS SELECT id, title, content
FROM article_table
现在你可以在视图里进行CRUD操作了,一切都很顺利,不过突然有一天,因为某种原因,你不得不把字段title改名为name:
ALTER TABLE article_table CHANGE title name VARCHAR(255) NOT NULL
改名很简单,但是我们程序里的代码可能都是按title这个名字来写的,如果改名程序肯定会挂!还好我们可以重建视图来屏蔽影响:
CREATE VIEW article_view (id, title, content) AS SELECT id, name, content
FROM article_table
也可以这样:
CREATE VIEW article_view AS SELECT id, name AS title, content
FROM article_table
对程序而言,一切都没有改变。当然,如果原始数据库表的变化过于剧烈,视图也是爱莫能助,那时就不得不修改程序了。
再比如,以前我们会使用关联查询来取复杂数据,有时候为了效率还不得不采用反范式的方式,通过冗余数据来降低关联查询。不过毕竟反范式是有悖于数据唯一性的,稍不留神,会引起数据错乱,有了视图以后,我们可以建立一个含有冗余数据的视图,虽然建立视图时使用的同样是关联查询,但是视图的内部机制可以保证其查询效率。
继续跟着我下面的步骤实战一下:
CREATE TABLE article_table (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
category_id INT UNSIGNED NOT NULL ,
title VARCHAR(255) NOT NULL ,
content TEXT NOT NULL
)
CREATE TABLE `category_table` (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
name VARCHAR(255) NOT NULL
)
一个很常见的需求:查询文章的同时还要得到文章所在类别的名字,无疑要使用关联查询:
SELECT article_table.*, category_table.name as category_name
FROM article_table LEFT JOIN category_table on article_table.category_id = category_table.id
为了避免关联查询对效率的影响,我们可能会在article_table里建立一个category_name冗余字段,算了,还是直接用视图吧:
CREATE VIEW article_view AS SELECT article_table.* , category_table.name AS category_nameFROM article_table LEFT JOIN category_table ON article_table.category_id = category_table.id
注:以上观点未严格测试,基本属于意淫范畴。