参考教材《数据库系统:原理、设计与编程(MOOC版)》,陆鑫 张凤荔 陈安龙
3.6 视图SQL语句
3.6.1 视图的概念
视图View是一种建立在SELECT查询结果集上的虚拟表。视图可以基于数据库表或其他视图构建,它本身没有自己的数据,而是使用了存储在基础表中的数据。基础表中数据的改变可以在视图中看到,若对视图中数据进行了修改,基础表的数据也要发生变化。对视图的操作其实是对它所给予的数据库表进行操作。
视图一旦被定义便作为对象存储在数据库中,但它本身并不存储数据,而是通过其虚拟视窗映射到基础表中的数据。对视图的操作与对数据库表的操作一样,可以对其数据进行查询和一定约束的修改与删除。
3.6.2 视图的创建与删除
1.视图的创建
视图由一个或几个基础表或其他视图的SELECT查询结果创建。
格式:
CREATE VIEW <视图名>[(列名1),(列名2),...] AS <SELECT查询>;
其中CREATE VIEW
为创建视图语句的关键字。一个数据库不允许有同名视图。在视图名称后,可以定义组成视图的各个列名。AS
关键字后为基础表的SELECT查询语句,其结果集为视图的数据。
例3-36
建立一个由基础课程数据构成的视图BasicCourseView:
CREATE VIEW BasicCourseView AS
SELECT CourseName, CourseCredit, CoursePeriod, TestMethod
FROM Course
WHERE CourseType='基础课';
GO
视图创建后,用户可以像访问数据表一样操作访问视图。例如使用SELECT语句查询该视图数据,并按课程名称排序输出:
SELECT *
FROM BasicCourseView
ORGER BY CourseName;
GO
返回的信息取决于视图中定义的列,而非基础表的信息。返回的行顺序也是按视图所指定的CourseName列升序排列,而非基础表中的行顺序。
2.视图的删除
格式:
DROP VIEW <视图名>;
删除该视图后,由此视图导出的其他视图也将失效。
3.视图的使用
视图是虚拟表,在数据库中只需要存储视图的结构定义,而不存储视图所包含的数据。对视图的操作访问如同对表的操作访问。使用视图这种对象模式,用户可以获得如下好处。
-
使用视图简化复杂SQL查询操作
通过视图,开发人员可以将复杂的查询语句封装在视图内,使外部程序只需要使用简单方式访问该视图,便可获取所需数据。例3-48
查询选修“数据库原理及应用”课程的学生名单。需要关联Course、Plan、Register、Student表:SELECT C.CourseName AS 课程名称, S.StudentID AS 学号, S.StudentName AS 姓名 FROM Course AS C, Plan AS P, Register AS R, Student AS S WHERE C.CourseID=P.CourseID AND C.CourseName='数据库原理及应用' AND P.CoursePlanID=R.CoursePlanID AND R.StudentID=S.StudentID; GO
为了省去这种复杂的SQL查询,可以定义一个名为DataBaseCoursView的视图:
CREATE DataBaseCourseView AS SELECT C.CourseName AS 课程名称, S.StudentID AS 学号, S.StudentName AS 姓名 FROM Course AS C, Plan AS P, Register AS R, Student AS S WHERE C.CourseID=P.CourseID AND C.CourseName='数据库原理及应用' AND P.CoursePlanID=R.CoursePlanID AND R.StudentID=S.StudentID; GO
创建完成后,外部程序就可以通过一个简单的SELECT语句查询视图数据:
SELECT * FROM DataBaseCourseView; GO
-
使用视图提高数据访问安全性
通过视图可以将基础数据库表中部分敏感数据隐藏起来,外部用户无法得知数据库表的完整数据,降低数据库被攻击的风险。此外,通过视图访问,用户只能查询和修改它们所能见到的数据,可保护隐私数据。例3-49
在选课管理系统数据库中,除教务管理部门用户外,其他用户只能浏览教师基本信息,如教师编号、姓名、性别、职称、所属学院,教师其他信息被隐藏。可定义视图来处理信息:CREATE VIEW BasicTeacherInfoView AS SELECT T.TeacherID AS 编号, T.TeacherName AS 教师姓名, T.TeacherGender AS 性别, T.TeacherTitle AS 职称, C.CollegeName AS 所属学院 FROM Teacher AS T, College AS C WHERE T.CollegeID=C.CollegeID; GO
然后外部程序就可以通过一个简单的SELECT语句查询视图数据:
SELECT * FROM BasicTeacherInfoView ORDER BY 所属学院, 编号; GO
在视图中也可以对视图查询的列进行排序,如上面的视图查询中。当然要使用视图的列,也就是AS后面的列名,即编号、教师姓名、性别、职称和所属学院。
-
提供一定程度的数据逻辑独立性
视图可提供一定程度的数据逻辑独立性。当数据表结构发生改变,只要视图结构不变,应用程序代码可以不做修改。这就是数据逻辑独立性。例3-50
在选课管理系统数据库中,如果Teacher的结构发生了改变,增加了“出生日期”字段,其表结构为(TeacherID, TeacherName, TeacherGender, BirthDay, TeacherTitle, CollegeID, TeacherPhone)。但只要定义教师基本信息的视图BasicTeacherInfoView结构不变,则使用该视图的外部程序不需要变动。 -
集中展示用户所感兴趣的特定数据
视图可以将部分用户不关心的数据进行过滤,仅仅提供它们所感兴趣的数据。例3-51
教务部门希望查询出没有被学生选修的课程名称及其教师信息。这里可以创建一个查询该信息的视图NoSelCourseView:CREATE VIEW NoSelCourseView AS SELECT C.CourseName AS 课程名称, T.TeacherName AS 教师, COUNT(R.CoursePlannID) AS 选课人数 FROM Course AS C JOIN Plan AS P ON C.CourseID=P.CourseID JOIN Teacher AS T ON P.TeacherID=T.TeacherID LEFT JOIN Register AS R ON P.CoursePlanID=R.CoursePlanID GROUP BY C.CourseName, T.TeacherName GO
如果外部程序只想查询没有被学生选修的课程名称及其教师信息,也就是视图NoSelCourseView中'选课人数'这列的数据为0的数据行:
SELECT 课程名称, 教师 FROM NoSelCourseView WHERE 选课人数=0; GO
到这里SQL语句的复习就已经全部结束了,我已经忘记前面复习过去的一些SQL语句格式了,所以还是纸上得来终觉浅。我计划后面有时间的时候就参考书上的一个项目,从头到尾实践一遍,加深理解。
在实际开发中,我是学习的.NET开发,常常使用一个交EntityFramework的ORM来操作数据。我感觉它很好用,甚至让我误以为现在的开发者只学ORM就可以了,不必再深入学习和掌握SQL了,后来我发现一些ORM用的非常好的高级开发者,它们虽然几乎不用SQL,但他们的SQL基础依然非常的扎实。就像一些厉害的开发者,在这个框架满地跑的时代,基本用不到数据结构和算法,但他们的数据结构和算法水平却依然非常高一样。SQL和数据结构与算法,都是开发者的很重要的内功,我认为这些厉害的开发者之所以开发水平高,跟他们内功强劲绝对是有关系的。希望我也能通过扎实自己的基础,来进步,来向他们看齐。希望看这篇文章的跟我一样的初学者,在学习框架之余,也抽时间慢慢补上这些自己有可能欠缺的东西。加油!