
视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。
对其中所引用的基础表来说,视图的作用类似于筛选。定义视图的筛选可以来自当前或其它数据库的一个或多个表,或者其它视图。通过视图进行查询没有任何限制,通过它们进行数据修改时的限制也很少。
视图是存储在数据库中的查询的SQL 语句,它主要出于两种原因:安全原因, 视图可以隐藏一些数据,如:社会保险基金表,可以用视图只显示姓名,地址,而不显示社会保险号和工资数等,另一原因是可使复杂的查询易于理解和使用。这个视图就像一个“窗口”,从中只能看到你想看的数据列。这意味着你可以在这个视图上使用SELECT *,而你看到的将是你在视图定义里给出的那些数据列:
既然视图的定义是基于基本表的,哪为什么还要定义视图呢?这是因为合理地使用视图能够带来许多好处:
1、 视图能简化用户 *** 作
视图机制使用户可以将注意力集中在所关心地数据上。如果这些数据不是直接来自基本表,则可以通过定义视图,使数据库看起来结构简单、清晰,并且可以简化用户的的数据查询 *** 作。例如,那些定义了若干张表连接的视图,就将表与表之间的连接 *** 作对用户隐藏起来了。换句话说,用户所作的只是对一个虚表的简单查询,而这个虚表是怎样得来的,用户无需了解。
2、 视图使用户能以多种角度看待同一数据
视图机制能使不同的用户以不同的方式看待同一数据,当许多不同种类的用户共享同一个数据库时,这种灵活性是非常必要的。
3、 视图对重构数据库提供了一定程度的逻辑独立性
数据的物理独立性是指用户的应用程序不依赖于数据库的物理结构。数据的逻辑独立性是指当数据库重构造时,如增加新的关系或对原有的关系增加新的字段,用户的应用程序不会受影响。层次数据库和网状数据库一般能较好地支持数据的物理独立性,而对于逻辑独立性则不能完全的支持。
在关许数据库中,数据库的重构造往往是不可避免的。重构数据库最常见的是将一个基本表“垂直”地分成多个基本表。例如:将学生关系Student(Sno,Sname,Ssex,Sage,Sdept),
分为SX(Sno,Sname,Sage)和SY(Sno,Ssex,Sdept)两个关系。这时原表Student为SX表和SY表自然连接的结果。如果建立一个视图Student:
[sql] view plain copy
CREATE VIEW Student(Sno,Sname,Ssex,Sage,Sdept)AS SELECT SX.Sno,SX.Sname,SY.Ssex,SX.Sage,SY.Sdept FROM SX,SY WHERE SX.Sno=SY.Sno;
这样尽管数据库的逻辑结构改变了(变为SX和SY两个表了),但应用程序不必修改,因为新建立的视图定义为用户原来的关系,使用户的外模式保持不变,用户的应用程序通过视图仍然能够查找数据。
当然,视图只能在一定程度上提供数据的逻辑独立,比如由于视图的更新是有条件的,因此应用程序中修改数据的语句可能仍会因为基本表构造的改变而改变。
4、视图能够对机密数据提供安全保护
有了视图机制,就可以在设计数据库应用系统时,对不同的用户定义不同的视图,使机密数据不出现在不应该看到这些数据的用户视图上。这样视图机制就自动提供了对机密数据的安全保护功能。例如,Student表涉及全校15个院系学生数据,可以在其上定义15个视图,每个视图只包含一个院系的学生数据,并只允许每个院系的主任查询和修改本原系学生视图。
5、适当的利用视图可以更清晰地表达查询
例如经常需要执行这样的查询“对每个学生找出他获得最高成绩的课程号”。可以先定义一个视图,求出每个同学获得的最高成绩:
[sql] view plain copy
CREATE VIEW VMGRADE
AS
SELECT Sno,MAX(Grade) Mgrade
FROM SC
GROUP BY Sno
然后用如下的查询语句完成查询:
[sql] view plain copy
SELECT SC.Sno,Cno FROM SC,VMGRADE WHERE SC.Sno = VMGRADE.Sno AND SC.Grade = VMGRADE.Mgrade;
二、数据准备
1、员工表
[sql] view plain copy
CREATE TABLE t_employee(
ID INT PRIMARY KEY AUTO_INCREMENT,
NAME CHAR(30) NOT NULL,
SEX CHAR(2) NOT NULL,
AGE INT NOT NULL,
DEPARTMENT CHAR(10) NOT NULL,
SALARY INT NOT NULL,
HOME CHAR(30),
MARRY CHAR(2) NOT NULL DEFAULT '否',
HOBBY CHAR(30)
)
插入数据:
[sql] view plain copy
INSERT INTO learning.t_employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'小红','女',20,'人事部','4000','广东','否','网球')
INSERT INTO learning.t_employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'明日','女',21,'人事部','9000','北京','否','网球')
INSERT INTO learning.t_employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'天天','男',22,'研发部','8000','上海','否','音乐')
INSERT INTO learning.t_employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'大大','女',23,'研发部','9000','重庆','否','无')
INSERT INTO learning.t_employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'王下','女',24,'研发部','9000','四川','是','足球')
INSERT INTO learning.t_employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'无名','男',25,'销售部','6000','福建','否','游戏')
INSERT INTO learning.t_employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'不知道','女',26,'销售部','5000','山西','否','篮球')
插入的结果:
请点击输入图片描述
然后再定义一张员工信息表:
[sql] view plain copy
create TABLE t_employee_detail(
ID INT PRIMARY KEY,
POS CHAR(10) NOT NULL,
EXPERENCE CHAR(10) NOT NULL,
CONSTRAINT `FK_ID` FOREIGN KEY(ID) REFERENCES t_employee(ID)
)
插入如下:
[sql] view plain copy
INSERT INTO t_employee_detail(ID,POS,EXPERENCE) VALUES(1,'人事管理','工作二年')
INSERT INTO t_employee_detail(ID,POS,EXPERENCE) VALUES(2,'人事招聘','工作二年')
INSERT INTO t_employee_detail(ID,POS,EXPERENCE) VALUES(3,'初级工程师','工作一年')
INSERT INTO t_employee_detail(ID,POS,EXPERENCE) VALUES(4,'中级工程师','工作二年')
INSERT INTO t_employee_detail(ID,POS,EXPERENCE) VALUES(5,'高级工程师','工作三年')
INSERT INTO t_employee_detail(ID,POS,EXPERENCE) VALUES(6,'销售代表','工作二年')
INSERT INTO t_employee_detail(ID,POS,EXPERENCE) VALUES(7,'销售员','工作一年')
内容:
请点击输入图片描述
三、使用案例
1. 语法
CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] VIEW [db_name.]view_name [(column_list)] AS select_statement [WITH [CASCADED | LOCAL] CHECK OPTION]
通过该语句可以创建视图,若给定了[OR REPLACE],则表示当已具有同名的视图时,将覆盖原视图。select_statement是一个查询语句,这个查询语句可从表或其它的视图中查 询。视图属于数据库,因此需要指定数据库的名称,若未指定时,表示在当前的数据库创建新视图。
表和数据库共享数据库中相同的名称空间,因此,数据库不能包含相同名称的表和视图,并且,视图的列名也不能重复。
在创建视图前应先看看是否有权限:
[sql] view plain copy
SELECT SELECT_priv,create_view_priv from mysql.user WHERE user='root'
Y表示有创建的权限
请点击输入图片描述
2、单表上创建视图
在员工表是创建视图
[sql] view plain copy
CREATE VIEW V_VIEW1(ID, NAME, SEX, AGE,DEPARTMENT) AS SELECT ID, NAME, SEX, AGE,DEPARTMENT FROM learning.t_employee
然后是显示内容:
[sql] view plain copy
SELECT * FROM V_VIEW1
请点击输入图片描述
3、多表上创建视图
[sql] view plain copy
CREATE VIEW V_VIEW2(ID, NAME, SEX, AGE,DEPARTMENT,POS,EXPERENCE) AS SELECT a.ID, a.NAME, a.SEX, a.AGE,a.DEPARTMENT,b.POS,b.EXPERENCE FROM learning.t_employee a,learning.t_employee_detail b WHERE a.ID=b.ID
显示结果
[sql] view plain copy
SELECT * FROM V_VIEW2
请点击输入图片描述
4、查看视图
(1)DESCRIBE 命令
[sql] view plain copy
DESCRIBE V_VIEW2
请点击输入图片描述
(2)SHOW TABLE STATUS
[sql] view plain copy
show TABLE status LIKE 'V_VIEW2'
请点击输入图片描述
(3)SHOW CREATE view命令
[sql] view plain copy
show CREATE view V_VIEW2
请点击输入图片描述
5、修改视图
(1)CREATE OR REPLACE命令
[sql] view plain copy
CREATE OR REPLACE VIEW V_VIEW1(ID, NAME, SEX) AS SELECT ID, NAME, SEX FROM learning.t_employee
请点击输入图片描述
(2) ALTER 命令
[sql] view plain copy
ALTER VIEW V_VIEW1(ID, NAME) AS SELECT ID, NAME FROM learning.t_employee
SELECT * FROM learning.v_view1
请点击输入图片描述
6、更新视图
在MySQL中,更新视图是指通过视图来插入(INSERT)、更新(UPDATE)和删除(DELETE)表中的数据。因为视图是一个虚拟表,其中没有数据,所以通过视图更新时,都是转换到基本表来更新。
更新视图时,只能更新权限范围内的数据。超出了范围,就不能更新。
更新前:
请点击输入图片描述
更新后:
[sql] view plain copy
UPDATE V_VIEW2 SET POS='高级工程师' WHERE NAME='天天'
请点击输入图片描述
对应 的真实表上的数据也发生改变 了
[sql] view plain copy
SELECT * FROM learning.t_employee_detail WHERE t_employee_detail.ID=3
请点击输入图片描述
不可更新的视图:
某些视图是可更新的。也就是说,可以在诸如UPDATE、DELETE或INSERT等语句中使用它们,以更新基表的内容。对于可更新的视图,在视图中的行和基表中的行之间必须具有一对一的关系。还有一些特定的其他结构,这类结构会使得视图不可更新。更具体地讲,如果视图包含下述结构中的任何一种,那么它就是不可更新的:
· 聚合函数(SUM(), MIN(), MAX(), COUNT()等)。
· DISTINCT
· GROUP BY
· HAVING
· UNION或UNION ALL
· 位于选择列表中的子查询
· Join
· FROM子句中的不可更新视图
· WHERE子句中的子查询,引用FROM子句中的表。
· 仅引用文字值(在该情况下,没有要更新的基本表)。
· ALGORITHM = TEMPTABLE(使用临时表总会使视图成为不可更新的)。
注意
视图中虽然可以更新数据,但是有很多的限制。一般情况下,最好将视图作为查询数据的虚拟表,而不要通过视图更新数据。因为,使用视图更新数据时,如果没有全面考虑在视图中更新数据的限制,就可能会造成数据更新失败。
CASCADED和LOCAL能不能决定视图是否能更新?
WITH[CASCADED|LOCAL] CHECK OPTION能不能决定视图是否能更新?这两个参数的基本定义如下:
LOCAL参数表示更新视图时只要满足该视图本身定义的条件即可。
CASCADED参数表示更新视图时需要满足所有相关视图和表的条件。没有指明时,该参数为默认值。
With check option的用法:
(with check option对于没有where条件的视图不起作用的)
[sql] view plain copy
CREATE VIEW V_VIEW3(ID, NAME,SEX,AGE,DEPARTMENT,SALARY, HOME, MARRY, HOBBY) AS SELECT ID, NAME, SEX,AGE,DEPARTMENT,SALARY,HOME,MARRY,HOBBY FROM learning.t_employee WHERE DEPARTMENT='人事部' WITH LOCAL CHECK OPTION
表示只限定插入部门为人事部的人。
请点击输入图片描述
然后插入一条:
[sql] view plain copy
INSERT INTO learning.V_VIEW3(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'会会会会','女',20,'人事部','4500','广东','否','网球')
看下结果:
[sql] view plain copy
SELECT * FROM learning.V_VIEW3
请点击输入图片描述
同时看真实表中的数据:
请点击输入图片描述
再来插入一条:
[sql] view plain copy
INSERT INTO learning.V_VIEW3(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'qqqqvasvas','女',20,'研发部','4500','上海','否','网球')
请点击输入图片描述
结果显示插入失败
对于with check option用法,总结如下:
通过有with check option选项的视图 *** 作基表(只是面对单表,对连接多表的视图正在寻找答案),有以下结论: 插入后的数据,通过视图能够查询出来就符合WITH CHECK OPTION 否则就不符合;
首先视图只 *** 作它可以查询出来的数据,对于它查询不出的数据,即使基表有,也不可以通过视图来 *** 作。
1.对于update,有with check option,要保证update后,数据要被视图查询出来
2.对于delete,有无with check option都一样
4.对于insert,有with check option,要保证insert后,数据要被视图查询出来
对于没有where 子句的视图,使用with check option是多余的
7、删除视图
[sql] view plain copy
DROP VIEW IF EXISTS 视图名
等
SQL 中with的用法如下:
CTE 之后必须跟随引用部分或全部 CTE 列的 SELECT、INSERT、UPDATE 或 DELETE 语句。也可以在 CREATE VIEW 语句中将 CTE 指定为视图中 SELECT 定义语句的一部分。
可以在非递归 CTE 中定义多个 CTE 查询定义。定义必须与以下集合运算符之一结合使用:UNION ALL、UNION、INTERSECT 或 EXCEPT。
CTE 可以引用自身,也可以引用在同一 WITH 子句中预先定义的 CTE。不允许前向引用。
不允许在一个 CTE 中指定多个 WITH 子句。例如,如果 CTE_query_definition 包含一个子查询,则该子查询不能包括定义另一个 CTE 的嵌套的 WITH 子句。
不能在 CTE_query_definition 中使用以下子句:
COMPUTE 或 COMPUTE BY
ORDER BY(除非指定了 TOP 子句)
INTO
带有查询提示的 OPTION 子句
FOR XML
FOR BROWSE
扩展资料
定义和使用递归 CTE 指南
下列指南适用于定义递归 CTE 的情况:
递归 CTE 定义至少必须包含两个 CTE 查询定义,一个定位点成员和一个递归成员。可以定义多个定位点成员和递归成员;但必须将所有定位点成员查询定义置于第一个递归成员定义之前。所有 CTE 查询定义都是定位点成员,但它们引用 CTE 本身时除外。
定位点成员必须与以下集合运算符之一结合使用:UNION ALL、UNION、INTERSECT 或 EXCEPT。在最后一个定位点成员和第一个递归成员之间,以及组合多个递归成员时,只能使用 UNION ALL 集合运算符。
定位点成员和递归成员中的列数必须一致。
递归成员中列的数据类型必须与定位点成员中相应列的数据类型一致。
递归成员的 FROM 子句只能引用一次 CTE expression_name。
在递归成员的 CTE_query_definition 中不允许出现下列项:
《PHP与mysql程序设计第四版》 498页视图章节
文档地址 网页链接也做了详细描述
摘抄自文档
The WITH CHECK OPTION clause can be given for an updatable view to prevent inserts to rows for which the WHERE clause in the select_statement is not true. It also prevents updates to rows for which the WHERE clause is true but the update would cause it to be not true (in other words, it prevents visible rows from being updated to nonvisible rows).
WITH CHECK OPTION 语句可以防止插入 可更新view 时候不满足view 的条件(比如我创建view 筛选的table_name 中age >5的数据,如果 我插入数据age小于等于5自然不行) ,他也可以用来防止 更新数据时本来是满足条件的要更新成不满足条件的情况(比如我创建view 的时候筛选条件是age >5 现在我要把其中一条本来是age >5 的数据更新成age =4 即小于5 就不ok 了 ) 换句话说就是 防止本来可见的 变成不可见
In a WITH CHECK OPTION clause for an updatable view, the LOCAL and CASCADED keywords determine the scope of check testing when the view is defined in terms of another view. When neither keyword is given, the default is CASCADED. The LOCAL keyword restricts the CHECK OPTION only to the view being defined. CASCADED causes the checks for underlying views to be evaluated as well.
LOCAL 和 CASCADED 关键字主要用在一个view 来源于另外一个view的情况 ,默认CASCADED ,LOCAL 只的是只关心本view 创建时的条件 (比如view_a 包含的子句中内容 是 select * from view_b where age >5 那么我插入到view_a 中的时候 只关心 age>5 就可以了)
如果 是CASCADED 表示还要关心 view_b 的条件( 比如
view_b 的条件是 select * from table_name where `salary` >3000 那么上面 在view_a创建数据的时候 age = 10 但是 salary 是2000 就无法插入)
下面是一个文档里面的例子 就不翻译了
Consider the definitions for the following table and set of views:
```
CREATE TABLE t1 (a INT)
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a <2
WITH CHECK OPTION
CREATE VIEW v2 AS SELECT * FROM v1 WHERE a >0
WITH LOCAL CHECK OPTION
CREATE VIEW v3 AS SELECT * FROM v1 WHERE a >0
WITH CASCADED CHECK OPTION
```
Here the v2 and v3 views are defined in terms of another view, v1. v2 has a LOCAL check option, so inserts are tested only against the v2 check. v3 has a CASCADED check option, so inserts are tested not only against its own check, but against those of underlying views. The following statements illustrate these differences:
```
mysql>INSERT INTO v2 VALUES (2)
Query OK, 1 row affected (0.00 sec)
mysql>INSERT INTO v3 VALUES (2)
ERROR 1369 (HY000): CHECK OPTION failed 'test.v3'
```
这个编辑器不支持MD 所以只能这样了
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)