Alex_McAvoy

想要成为渔夫的猎手

SQL 视图的数据定义

【视图】

视图是从一个或几个基本表导出的表,其是一个虚表

数据库中仅存放视图定义,不存放其具体数据,这些具体数据仍在原来的基本表中,因此基本表中的数据一旦发生变化,从视图中查询出的数据也就随之改变了

视图一经定义,就可以与基本表一样被查询、删除,但对其更新有一定的限制,此外,还可以定义基于视图的视图

视图机制使用户可以将注意力集中在他所关心的数据上,如果这些数据不是直接来自基本表,则可以通过定义视图,使用户眼中的数据库结构简单、清晰,以简化用户的数据查询操作

同时,视图使用户以多种角度看待同一数据,当许多不同种类的用户使用同一个数据库时,这种灵活性是非常重要的

而在设计数据库应用系统时,对不同用户定义不同的视图,使机密数据不出现在不应看到这些数据的用户视图上,这样就由视图的机制自动提供了对机密数据的安全保护功能

此外,视图对重构数据库提供了一定程度的逻辑独立性

【视图定义】

基本语法

在 SQL 中,建立视图的语法如下

1
2
3
CREATE VIEW <视图名> [(<列名1> [,<列名2>]...[,<列名n>])]
AS <子查询>
[WITH CHECK OPTION];

<子查询> 可以是任意的 SELECT 查询语句,RDBMS 执行建立视图的语句时,只是将视图定义存入数据字典,没有执行其中的 SELECT 语句,仅当对数据查询时,才按视图的定义从基本表中将数据查出

列名

<列名> 是要组成视图的列的新名,如果全部省略,则该视图的列名将默认使用 SELECT 子句目标列的列名

如下例,通过基本表 student 建立 CS 系学生的视图 is_student,要求视图中包含学号 Sno、姓名 Sname、年龄 Sage

1
2
3
4
5
CREATE VIEW is_student
AS
SELECT Sno, Sname, Sage
FROM student
WHERE Sdept='CS';

该例中省略了组成视图的列,此时视图由子查询中 SELECT 子句中的三个列名组成

如果不省略,则 <列名> 的与 SELECT 子句目标列的一一对应,要求 <列名> 个数与 SELECT 子句目标列的个数相同

如下例,通过基本表 student 建立 CS 系学生的视图 is_student,要求视图中包含基本表中的学号 Sno、姓名 Sname、年龄 Sage,同时要求视图中的列名依次为 number、name、age

1
2
3
4
5
CREATE VIEW is_student(number, name, age)
AS
SELECT Sno, Sname, Sage
FROM student
WHERE Sdept='CS';

此外,若视图由 SELECT * 建立,则必须要指定 <列名>,使用该种方法建立的视图可扩充性差,一旦基本表的结构改变,则基本表与视图的映射将被破坏,只能重新建立视图,因此应尽量避免使用该方法创建视图

例如,通过基本表 student 建立包含所有男生记录的视图 f_student

1
2
3
4
5
CREATE VIEW f_student(f_sno, name, sex, age, dept)
AS
SELECT *
FROM Student
WHERE Ssex='男';

保证谓词条件

WITH CHECK OPTION 代表对视图进行修改、删除、插入操作时,行要满足视图定义的谓词条件(子查询中的条件表达式)

如下例,通过基本表 student 建立 CS 系学生的视图 is_student,要求进行修改和插入操作时仍需保证该视图只有信息系学生

1
2
3
4
5
6
CREATE VIEW is_student
AS
SELECT Sno, Sname, Sage
FROM student
WHERE Sdept='CS'
WITH CHECK OPTION;

该例中加上了 WITH CHECK OPTION 子句,这样以后对该视图进行修改、删除、插入操作时,RDBMS 会自动加上 Sdept='IS' 的条件:

  • 修改:自动加上 Sdept='IS' 的条件
  • 删除:自动加上 Sdept='IS' 的条件
  • 插入:自动检查 Sdept='IS' 的条件,若不是,则拒绝该插入操作;若未提供 Sdept 属性值,则自动设为 'IS'

视图类型

若视图是从单个基本表导出的,且仅是去除了基本表的某些行列,但保留了主码,则称这类视图为行列子集视图

例如,通过基本表 student 建立 CS 系学生的视图 is_student,要求视图中包含学号 Sno、姓名 Sname、年龄 Sage

1
2
3
4
5
CREATE VIEW is_student
AS
SELECT Sno, Sname, Sage
FROM student
WHERE Sdept='CS';

若视图是从多个基本表导出的,则称这类视图为基于多个基表的视图

例如,通过基本表 student 和 sc 来建立 CS 系选修了 1 号课程的学生的视图 cs1,要求视图中包含学号 Sno、姓名 Sname、成绩 Grade

1
2
3
4
5
6
7
CREATE VIEW cs1 (Sno, Sname, Grade)
AS
SELECT student.Sno, student.Sname, SC.Grade
FROM student, sc
WHERE student.Sdept='CS' AND
Student.Sno=SC.Sno AND
SC.Cno='1';

视图不仅可以建立在一个或多个基本表上,也可以建立在一个或多个已定义好的视图上,这类视图称为基于视图的视图

例如,通过视图 cs1 来建立成绩在 90 分以上 的学生的视图 cs2

1
2
3
4
5
CREATE VIEW cs2
AS
SELECT Sno, Sname, Grade
FROM cs1
WHERE Grade>=90;

由于视图中的数据并不实际存储,因此定义视图时可以根据应用的需要设置一些派生属性列,这些派生属性由于在基本表中并不实际存在,因此被称为虚拟列,这些带虚拟列的视图被称为带表达式的视图

例如,通过基本表 student 建立一个反映学生出生年份的视图 birth,已知该表中所有学生的入学时间都是 2017 年

1
2
3
4
CREATE VIEW birth(Sno, Sname, Sbrith)
AS
SELECT Sno, Sname, 2017-Sage
FROM student;

当使用聚集函数和 GROUP BY 子句的查询来定义视图时,这种视图称为分组视图

例如,通过基本表 sc 建立一个视图 avg_grade,包括学生学号和平均成绩

1
2
3
4
5
CREATE VIEW avg_grade(Sno, Gavg)
AS
SELECT Sno, AVG(Grade)
FROM SC
GROUP BY Sno;

【视图删除】

若基本表删除被删除,那么由该基本表导出的所有视图均无法使用,但是视图的定义还没有从数据字典中删除,此时就需要调用视图删除语句,将视图删除

在 SQL 中,删除视图的语法为

1
DROP VIEW <视图名> [CASCADE];

执行该语句后,视图的定义将从数据字典中删除,如果该视图上还导出了其他视图,那么可以使用级联短语 CASCADE 将该视图及其导出的视图一并删除

感谢您对我的支持,让我继续努力分享有用的技术与知识点!