思维导图:
笔记:3.7 视图
---
**概念:**
- **视图**:从一个或多个基本表(或其他视图)导出的虚表。数据库只保存定义,不保存实际数据。
- **视图与基本表**:任何基本表的数据改变都会反映在视图上。
- **视图的比喻**:视图就像是一个窗口,通过它可以看到数据库中特定的数据及其变化。
**操作:**
- 可以查询、删除视图。
- 可以基于一个视图定义另一个视图。
- 更新视图(增、删、改)有限制。
3.7.1 定义视图:
1. **建立视图**:使用`CREATE VIEW`命令。
2. **语法**:`CREATE VIEW <视图名> [(<列名>[,<列名>]…)] AS <子查询> [WITH CHECK OPTION];`
3. **子查询**:可以是任意的`SELECT`语句。
4. **WITH CHECK OPTION**:确保对视图的更新、插入、删除满足视图定义的条件。
5. **视图属性列名**:
- 可全部省略或指定。
- 必须指定的情况:
1. 目标列不是单纯属性名,而是聚集函数或表达式。
2. 多表连接时选择了同名列作为视图字段。
3. 在视图中为某列使用新的名字。
**示例:**
- [例3.84]:建立信息系学生的视图。
- [例3.85]:建立信息系学生的视图,加入`WITH CHECK OPTION`。
- [例3.86]:在多个基本表上建立视图,包括学号、姓名、成绩。
- [例3.87]:基于视图建立新的视图。
---
**重点理解**:视图的核心概念是其虚拟性。它不直接保存数据,而是提供一个数据窗口。因此,视图的数据与其基础表或视图始终保持同步。这为数据库查询和管理提供了强大的灵活性。
我的理解:
视图(View)是数据库中的一个核心概念。要理解它,可以通过以下几个方面来探讨:
1. **数据的"窗口"**:
- 想象你有一个巨大的仓库,其中堆满了各种物品。每次需要检查物品时,你不可能浏览整个仓库。相反,你可能只关心某一部分的物品。视图就像是仓库的一个窗口,它允许你只查看你关心的部分。
2. **虚拟表**:
- 虽然视图看起来和感觉像一个真实的表,但实际上它并不存储数据。它仅仅是一个查询的结果。每次查询视图时,背后的查询都会被重新执行,从而展现最新的数据。
3. **数据的过滤和转换**:
- 视图可以作为数据的过滤器,展现原始表中的部分数据或转换数据。例如,可以有一个视图只展示某个部门的员工,或将价格数据从美元转换为欧元。
4. **安全性**:
- 通过视图,可以为不同的用户提供不同级别的数据访问权限。例如,经理可以看到员工的全部信息,而前台员工只能看到联系方式。
5. **简化复杂性**:
- 如果有一个非常复杂的查询,需要连接多个表并进行多种转换,那么可以通过创建视图来简化这个过程。用户只需查询这个视图,而不必每次都执行复杂的查询。
6. **独立性**:
- 视图可以作为一个抽象层,提供对数据的统一访问方式,即使背后的表结构发生变化,只要视图的定义仍然有效,应用程序就不需要更改。
想象视图就像是一副眼镜,你穿上它看世界(数据库),只看到你想看到的部分,而且这部分是实时更新的,即时反映现实世界(实际表)的变化。
关于数据库视图
1. **视图的定义**
- 视图是一种虚拟表,不真实存储数据。
- 定义视图时,列名可以省略。如果省略,则由子查询中的SELECT子句的列名组成。
- 使用`CREATE VIEW`语句定义视图。
- 在对视图查询时,实际上是在执行背后的`SELECT`语句。
2. **WITH CHECK OPTION**
- `WITH CHECK OPTION`确保视图的更新、插入或删除操作满足定义中的条件。
- 例如:如果视图定义为只展示信息系的学生,那么后续的数据修改都必须满足此条件。
3. **行列子集视图**
- 若视图是从单个基本表导出,并只展示部分行和列但保留了主码,则称为行列子集视图。
4. **视图的来源**
- 可以基于单个或多个基本表。
- 可以基于已定义的一个或多个视图。
- 可以基于基本表和视图的组合。
5. **删除视图**
- 使用`DROP VIEW`语句。
- `CASCADE`选项可以级联删除由某个视图派生的所有视图。
- 删除基本表后,由该表导出的所有视图变得不可用,但其定义仍然存在。要删除这些视图,需要显式使用`DROP VIEW`。
6. **例子分析**
- `[例3.84]`: 创建信息系学生的视图,只包含学号、姓名、和年龄。
- `[例3.85]`: 同上,但有`WITH CHECK OPTION`保证只有信息系的学生。
- `[例3.86]`: 创建视图显示信息系选了1号课程的学生及其成绩。
- `[例3.87]`: 基于上一个视图,进一步筛选成绩超过90分的学生。
- `[例3.91]`: 删除视图的示例,展示了不带CASCADE和带CASCADE的差异。
---
**笔记:3.7.2 查询视图**
1. **视图查询的基本**
- 视图定义后,可像基本表一样查询。
- 对视图的查询转换为对基本表的查询,这一转换过程称为视图消解(view resolution)。
2. **视图消解的实例**
- `[例3.92]`: 查询信息系年龄小于20岁的学生的视图,转换后查询基本表。
- `[例3.93]`: 查询选修了1号课程的信息系学生,涉及视图IS_Student和基本表SC的连接。
3. **视图查询的限制**
- 虽然大多数查询可以转换,但某些情况下会出现问题。
- `[例3.94]`: 查询S_G视图中平均成绩在90分以上的学生,原查询因WHERE子句中使用聚集函数而出现语法错误。正确的查询应使用HAVING子句。
4. **行列子集视图 vs 非行列子集视图**
- 多数数据库对行列子集视图查询能正确转换。
- 非行列子集视图的查询可能无法转换。这种情况下,建议直接查询基本表。
5. **视图 vs 派生表**
- 定义视图后,其定义保存在数据字典,可供后续查询引用。
- 派生表在查询执行时临时定义,执行后即删除。
---
笔记:3.7.3 更新视图
1. **基本概念**:
- 更新视图: 通过视图来插入、删除、修改数据。
- 视图是虚表, 更新要转换为对基本表的更新。
- 转换过程称为视图消解(view resolution)。
2. **保护视图数据**:
- 使用`WITH CHECK OPTION`子句防止用户修改不属于视图范围的基本表数据。
3. **实例**:
- `[例3.95]`: 修改学生姓名通过视图。转换后,更新基本表。
- `[例3.96]`: 插入新学生记录。系统自动添加系名到基本表。
- `[例3.97]`: 删除记录。转换后,删除基本表中的对应数据。
4. **视图更新的限制**:
- 不是所有视图都可更新。
- 有些视图更新不能有意义地转换成基本表更新,如S_G视图。
- 通常, 行列子集视图可更新。其他视图可能可更新或不可更新。
5. **各数据库系统的规定**:
- 关系数据库管理系统通常只允许对行列子集视图更新。
- 各系统有不同规定,如DB2:
1. 由多个基本表导出的视图不可更新。
2. 字段来自表达式或常数的视图只允许DELETE。
3. 字段来自聚集函数的视图不可更新。
4. 含有`GROUP BY`子句或`DISTINCT`短语的视图不可更新。
5. 视图中有嵌套查询且涉及的表也是基本表, 则不可更新。
---
3.7.4 视图的作用
1. **简化操作**:
- 视图使得用户专注于他们关心的数据。
- 可以隐藏复杂的表连接操作,用户只需简单查询虚表。
2. **多角度看数据**:
- 同一数据可通过不同视图供不同用户查看。
- 提供对同一数据的多种解读。
3. **逻辑独立性**:
- 视图对数据库的逻辑结构变动有一定的容忍性。
- 例如,将一个表分割成两个时,可以通过视图维护原有的查询接口。
4. **数据安全**:
- 视图可限制用户访问的数据范围。
- 提供了对敏感数据的安全保护。
5. **表达清晰的查询**:
- 通过视图,可以先定义常用的数据计算或筛选,然后基于这些视图进行进一步查询。
---
**视图的重点、难点与易错点总结:**
### 重点:
1. **视图定义:** 理解视图是什么,即它是一个虚拟的表,不真正存储数据,而是基于一个或多个实际的表来展示数据的方式。
2. **视图的用途:**
- 数据简化:隐藏复杂的SQL查询。
- 数据安全:为不同的用户显示不同的数据子集。
- 数据抽象:隐藏数据的物理细节。
3. **视图创建与修改:** 使用`CREATE VIEW`语句来创建视图,以及如何用`ALTER VIEW`来修改视图。
4. **视图的更新:** 并不是所有的视图都可以更新,需要理解什么样的视图是可以更新的。
### 难点:
1. **视图的消解:** 当通过视图查询或更新数据时,如何将这些操作转化为对基础表的操作。
2. **可更新的视图:** 判定一个视图是否可以进行插入、更新或删除操作的规则。
3. **WITH CHECK OPTION:** 该选项确保对视图的修改都符合视图的定义条件,从而避免误操作。
4. **复杂视图:** 包含聚合函数、分组、连接等操作的视图会带来额外的复杂性。
5. **性能考虑:** 使用视图可能导致性能问题,尤其是在涉及多个连接、子查询和复杂计算的视图中。
### 易错点:
1. **误认为视图存储数据:** 视图不真正存储数据,它只是基于实际表的查询。
2. **更新不可更新的视图:** 尝试更新包含聚合函数或连接操作的视图可能会导致错误。
3. **视图依赖:** 如果修改了视图所依赖的基础表结构,视图可能会失效。
4. **性能假设:** 错误地假设使用视图总是更高效,而不是直接查询基础表。
5. **复杂视图的管理:** 当视图基于其他视图,维护和理解视图的逻辑和依赖关系可能变得复杂。
6. **权限问题:** 忘记给用户赋予视图的适当权限,导致他们无法访问视图。
对于数据库开发者和管理员来说,理解上述重点和注意易错点,以及深入研究难点,将有助于更有效地使用和管理视图。