【期末不挂科】第三章 关系数据库标准语言 SQL

博主介绍:

我是了 凡 微信公众号【了凡银河系】期待你的关注。未来大家一起加油啊~


3.1 SQL 概述

3.1.1 SQL 的产生与发展

SQL 标准的进展过程
目前,没有一个数据库系统能够支持SQL标准的所有概念和特性。大部分数据库系统能支持SQL/92标准中的大部分功能以及SQL99、SQL2003中的部分新概念。同时,许多软件厂商对SQL基本命令集还进行了不同程度的扩充和修改,又可以支持标准以外的一些功能特性

3.1.2 SQL的特点

  • 综合统一
  • 高度非过程化
  • 面向集合的操作方式
  • 以同一种语法结构提供多种使用方式
  • 语言简洁,易学易用

3.1.3 SQL的基本概念

支持SQL的关系数据库管理系统同样支持关系数据库三级模式结构。

SQL 对关系数据库模式的支持
其中外模式包括若干视图(view)和部分基本表(base table),模式包括若干基本表,内模式包括若干存储文件(stored file)。

3.2 学生-课程数据库

第一步就是先要建立一个课程数据库, 举例三张表

  • 学生表:Student(Sno,Sname,Ssex,Sage,Sdept)
  • 课程表:Course(Cno,Cname,Cpno,Ccredit)
  • 学生选课表:SC(Sno,Cno,Grade)

3.3 数据定义

SQL 的数据定义语句
一个关系数据库管理系统的实例(instance)中可以建立多个数据库,一个数据库中可以建立多个模式,一个模式下通常包括多个表、视图和索引等数据库对象。

3.3.1 模式的定义与删除

1.定义模式

在SQL中,模式定义语句如下:

Create schema <模式名>authorization<用户名>;
  • 如果没有指定<模式名>,那么<模式名>隐含为<用户名>。要创建模式,调用该命令的用户必须拥有数据库管理员权限,或者获得了数据库管理员授予的Create schema的权限。

  • 目前,在Create schema中可以接受create table,create view 和 grant子句。也就是说用户可以在创建模式的同时在这个模式定义中进一步创建基本表、视图,定义授权。

2.删除模式

在SQL中,删除模式语句如下:

drop schema<模式名><cascade|restrict>;

其中Cascade 和 restrict 两者必须选起义。选择了cascade(级联),表示在删除模式的同时把该模式中所有
的数据库对象全部删除;选择了restrict(显示)表示如果该模式中已经定义了下属的数据库对象(如表、视图
等),则拒绝该删除语句的执行。只有当该模式中没有任何下属的对象时才能执行DROP SCHEMA语句。

3.3.2 基本表的定义、删除与修改

1.定义基本表

SQL 语言使用 Create table语句定义基本表,其基本格式如下:

create table<表名> (<列名><数据类型>[列级完整性约束条件]
                    [,<列名><数据类型>[列级完整性约束条件]]
                    ...
                    [,<表级完整性约束条件>]
);

建表的同时通常还可以定义与该表有关的完整性约束条件,这些完整性约束条件被存入系统的数据字典中,当用户操作表中数据时由关系数据库管理系统自动检查该操作是否违背这些完整性约束条件。如果完整性约束条件涉及该表的多个属性列,则必须定义在表级上,否则可以定义在列级也可以定义在表级。

例如,建立一个“学生”表Student。

create table student()
    (Sno CHAR(9) PRIMARY KEY,
    Sname CHAR(20) UNIOUE,
    Ssex CHAR(2),
    Sage SMALLINT,
    Sdept CHAR(20)
    );

系统执行该CREATE TABLE语句后,就在数据库中建立一个新的空“学生”表Student,并将有关“学生”表的定义及有关约束条件存放在数据字典中。

2.数据类型

关系模型中一个很重要的概念是域。每一个属性来自一个域,它的取值必须是域中的值。

在SQL标准支持多种数据类型,以下列出常用几种数据类型。

在这里插入图片描述
在这里插入图片描述

3.模式与表

每一个基本表都属于某一个模式,一个面试包含多个基本表。当定义基本表时一般可以有三种方法定义它所属的模式。

例如,定义一个学生-课程模式S-T。现在要在S-T中定义Student、Cource、SC等基本表。

方法一,在表名中明显地给出模式名。

create table "S-T".Student(...);           /* Student 所属的模式是S-T*/
create table "S-T".Course(...);        -- Course所属的模式是 S-T
create table "S-T".SC(...);            -- SC 所属的模式是S-T

方法二,在创建模式语句中同时创建表
方法三,设置所属的模式,这样在创建表时表名中不必给出模式名。

当用户创建基本表(其他数据库对象也一样)时若没有指定模式,系统根据搜索路径(search path)来确定该对象所属的模式。

4.修改基本表

随着应用环境和应用需求的变换,有时需要修改已建立好的基本表。SQL 语言用ALTER RABLE语句修改基本表,其一般格式为

alter table<表名>
[ADD [COLUMN]<新列名><数据类型>[完整性约束]]
[ADD<表级完整性约束>]
[DROP[COLUMN]<列名i>[CASCADE|RESTRICT]]
[DROP CONSTRAINT<完整性约束名>[RESTRICT|CASCADE]]
[ALTER COLUMN<列名><数据类型>];

其中<表名>是要修改的基本表,ADD子句用于增加新列、新的列级完整性约束条件和新的表级完整性约束条件。DROP COLUMN 子句用于删除表中的列,如果指定了CASCADE短语,则自动删除引用了该列的其他对象,比如视图:如果指定了RESTRICT短语,则如果该列被其他对象引用,RDBMS将拒绝删除该列。DROP CONSTRAINT子句用于删除指定的完整性约束条件。ALTER COLUMN子句用于修改原有的列定义,包括修改列名和数据类型。

5.删除基本表

当某个基本表不再需要时,可以使用DROP TABLE语句删除它。其一般格式为:

drop table <表名>[RESTRICT|CASCADE];

若选择RESTRICT,则该表的删除是有限制条件的。删除的基本条件表不能被其他表的约束所引用(如 CHECK,FOREIGN KEY 等约束),不能有视图,不能有触发器(trigger),不能有存储过程或函数等。如果存在这些依赖该表的对象,则此表不能被删除。

3.3.3 索引的建立与删除

当表的数据量比较大时,查询操作会比较耗时。建立索引是加快查询速度的有效手段。数据库索引类似于图书后面的索引,能快速定位到需要查询的内容。用户可以根据应用环境的需要再基本表上建立一个或多个索引,以提供多种存取路径,加快查找速度。

数据库索引有多种类型,常见索引包括顺序文件上的索引、B+树索引、散列(hash)索引、位图索引等。

建立与删除索引由数据库管理员或表的属主(owner),即建立表的人,负责完成。关系数据库管理系统在执行查询时会自动选择合适的索引作为存取路径,用户不能显式地选择索引。

1.建立索引

建立索引使用CREATE INDEX语句,格式为:

create [UNIQUE][CLUSTER]INDEX<索引名>
ON<表名>(<列名>[<次序>][,<列名>[<次序>]]...);

其中,<表名>是建立索引的基本表的名字。索引可以建立在改表的一列或多列上,各列名之间用逗号分隔。每个<列名>后面还可以用<次序>指定索引值的排列次序,可选ASC(升序)或DESC(降序),默认值为ASC。

2.修改索引

对于已经建立的索引,如果需要对其重新命名,可以使用ALTER INDEX语句。格式为:

alter index<旧索引名>rename TO<新索引名>;

3.删除索引

索引一经建立就由系统使用和维护,不需用户干预。建立索引是为了减少查询操作的时间,但如果数据增、删、改频繁,系统会花费许多时间来维护索引,从而降低了查询效率。

删除索引使用DROP INDEX语句,格式为:

drop index<索引名>;

3.3.4 数据字典

数据字典是关系数据库管理系统内部的一组系统表,它记录了数据库中所有的定义信息,包括关系模式定义、视图定义、索引定义、完整性约束定义、各类用户对数据库的操作权限、统计信息等。

3.4 数据查询

数据查询是数据库的核心操作。SQL提供了SELECT语句进行数据查询,改语句具有灵活的使用方式和丰富的功能。

3.4.1 单表查询

单表查询是指仅涉及一个表的查询。

1.选择表中的若干列

选择表中的全部或部分列即关系代数的投影运算。

  • 查询指定列
    例如,查询全体学生的学号与姓名

    select Sno,Sname from Student;
    

    执行过程:从Student表中取出一个元组,取出改元组在属性Sno和Sname上的值,形成一个新的元组作为输出。对Student表中的所有元组做相同的处理,最后形成一个结果关系作为输出。

  • 查询全部列
    例如,查询全体学生详细记录

    select * from Student;
    

    等价于

    select Sno,Sname,Ssex,Sage,Sdept from Student;
    
  • 查询经过计算的值
    select 子句的<目标列表达式>不仅可以是表中的属性列,也可以是表达式
    例如,查询全体学生的姓名及其出生年份

    select Sname, 2014-Sage from Student;  --查询结果第2列是一个算术表达式
    

2.选择表中的若干元组

  • 消除取值重复的行
    两个本来并不完全相同的元组在投影到指定的某些列上后,可能会变成相同的行。可以用DISTINCT消除它们。

  • 查询满足条件的元组
    查询满足指定条件的元组可以通过WHERE子句实现。

    在这里插入图片描述

3.ORDER BY子句

用户可以用ORDER BY子句对查询结果按照一个或多个属性列的升序(ASC)或降序(DESC)排列,默认为升序。

例如,查询选修了3号课程的学生的学号及其成绩,查询结果按分数的降序。

select Sno,Grade from SC where Cno='3' order by grade desc;

或相反,默认升序。

4.聚集函数

为了进一步方便用户,增强检索功能,SQL提供了许多聚集函数,主要有:

count(*)                         -- 统计元组个数
count([distinct|all]<列名>)       -- 统计一列中值的个数
sum([distinct|all]<列名>)       -- 计算一列值的总和(此列必须是数值型)
avg([distinct|all]<列名>)       -- 计算一列值的平均值(此列必须是数值型)
max([distinct|all]<列名>)       -- 求一列值中的最大值
min([distinct|all]<列名>)       -- 求一列值中的最小值

如果指定DISTINCT 短语,则表示在计算时要取消指定列中的重复值。如果不指定DISTINCT 短语或指定ALL 短语(ALL为默认值),则表示不取消重复值。

5.GROUP BY子句

GROUP BY子句将查询结果按某一列或多列的值分组,值相等的为一组。对查询结果分组的目的是为了细化聚集函数的作用对象。如果未对查询结果分组,聚集函数将作用于整个查询结果。分组后聚集函数将作用于每一组,即每一组都有一个函数值

例如,求各个课程号及相应的选课人数

select Cno,COUNT(Sno) from SC GROUP BY Cno;

查询结果假定为:

在这里插入图片描述

如果分组后还要求按一定的条件对这些组进行筛选,最终只输出满足指定条件的组,则可以使用HAVING短语指定筛选条件。

例如,查询选修了三门以上课程的学生学号。

select Sno from SC group by Sno having count(*)>3;

3.4.2 连接查询

若一个查询同时涉及两个以上的表,则称之为连接查询。连接查询是关系数据库中最主要的查询,包括等值连接查询、自然连接查询、非等值连接查询、自身连接拆线呢、外连接查询和复合条件连接查询等。

1.等值与非等值连接查询

连接查询的 where 子句中用来连接两个表的条件称为连接条件或连接谓词,其一般格式为

[<表名 1>.] <列名 1><比较运算符>[<表名 2>.]<列名 2>

其中比较运算符主要有=、>、<、>=、<=、!=(或<>)等。
此外连接谓词还可以使用下面形式;

[<表名 1>.]<列明 1>BETWEEN [<表名 2>.] <列名 2>AND[<表名2>.]<列名 3>

当连接运算符为=时,称为等值连接。使用其他运算符称为非等值连接连接谓词中的列名称为连接字段。连接条件中的各连接字段类型必须是可比的,但名字不必相同。

例如,查询每个学生及其选修课程的情况。

学生情况在Student表中,学生选课情况在SC表中,所以这次查询涉及了两张表。这两张表之间的联系是通过公共属性Sno实现的。

Select Student.*,SC.*  from Student,SC where Student.Sno = SC.Sno;  -- 将Student与SC中同一学生的元组连接起来

查询结果:

在这里插入图片描述

2.自身连接

连接操作不仅可以在两个表之间进行,也可以是一个表与其自己进行连接,称为表的自身连接。

例如,查询每一门课的间接先修课(即先修课的先修课)

比如说我要先学数据库但是学数据库之前就要先学数据结构,但是我要去学数据结构就要先学 PASCAL 语言。这就是间接先修课。

为此,要为 Course 表取两个别名,一个是FIRST,另一个是 SECOND。

在这里插入图片描述

完成该查询的 SQL 语句为

select FIRST.Cno,SECOND.Cpno 
from Course FIRST.Course SECOND 
where FIRST.Cpno=SECOND.Cno;

结果为:
在这里插入图片描述

3.外连接

假设有这样的两个表格:Student与 SC表 Student为所有的学生,而SC表为学生的选课表,我们可以知道王敏和张力没有选课,当使用Student.Sno=Sc.Sno的条件时,我们会发现无法出现王敏和张立的信息

为此,此时可以这样使用:

select Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
from Student left outer join sc on (Student.Sno=SC.Sno);

结果为:

在这里插入图片描述

4.多表连接

连接操作除了可以是两表连接、一个表与其自身连接外,还可以是两个以上的表进行连接,后者通常称为多表连接

例如,查询每个学生的学号、姓名、选修的课程名及成绩。本查询涉及三个表,完成该查询的SQL语句如下:

select Student,Sno,Sname,Cname,Grade
from Student,SC,Course
where Student.Sno=SC.Sno AND sc.Cno=Course.Cno;

关系数据库管理系统在执行多表连接时,通常是先进行两个表的连接操作,再将其连接结果与第三个表进行连接。

3.4.3 嵌套查询

在SQL 语言中,一个 SELECT-FROM-WHERE语句称为一个查询块嵌套在另一个查询块的WHERE 子句或 HAVING 短语的条件中的查询称为嵌套查询(nested query)。

例如:

select Sname       -- 外层查询或父查询
from Student
where Sno IN
            (select Sno    -- 内层查询或子查询
            from SC
            where Cno='2');

1.带有IN谓词的子查询

在嵌套查询中,子查询的结果往往是一个集合,所以谓词IN是嵌套查询中最经常使用的谓词。

例如,查询与“王林”同一个系学习的学生的所有信息

一般我们的思路是先拿到“王林”的系名,在从系里查找一起学习的学生的所有信息,所以需要两步骤:

  • 第一步:查找“王林”所在的系名,假设结果为C1

    select dept from dbo.s where sn='王林'
    
  • 第二步:查找一个系学习的学生的所有信息

    select * from dbo.s where dept='C1'
    

但是这样看明显很麻烦而且还要多次查询比较耗时占用资源,所以我们使用 IN 谓词嵌套查询:

select * from dbo.s where dept in(select dept from dbo.s where sn='王林')

2.带有比较运算符的子查询

带有比较运算符的子查询是指父查询与子查询之间用比较运算符进行连接。当用户能确切知道内层查询返回的是单个值时,可以用>、<、=、>=、<=、!=或<>等比较运算
符。

其使用方法和 IN 一致。
例如,由于一个学生可能在一个系学习,也就是说内查询的结果是一个值,因此可以用=代替 IN:

select Sno,Sname,Sdept
from Student
where Sdept =
        (select Sdept
        from Student
        where Sname='刘辰');

3.带有ANY(SOME)或ALL谓词的子查询

子查询返回单值时可以用比较运算符,但返回多值时要用ANY(有的系统用SOME)或ALL谓词修饰符。而使用ANY或ALL谓词时则必须同时使用比较运算符。其语义为:

> ANY 大于子查询结果中的某个值
> ALL  大于子查询结果中的所有值
< ANY 小于子查询结果中的某个值
< ALL 小于子查询结果中的所有值

>= ANY  大于等于子查询结果中的某个值
>= ALL  大于等于子查询结果中的所有值
<= ANY 小于等于子查询结果中的某个值
<= ALL 小于等于子查询结果中的所有值


= ANY 等于子查询结果中的某个值
= ALL 等于子查询结果中的所有值(通常没有实际意义)

!=(<>) ANY 不等于子查询结果中的某个值
!=(<>) ALL 不等于子查询结果中的任何一个值

例如,查询其他系中比计算机科学系某一学生年龄小的学生姓名和年龄

select Sname,Sage 
from Student 
where Sage < any(select Sage 
                from Student  
                where Sdept='CS') 
AND Sdept <> 'CS';

结果如下:
在这里插入图片描述

4.带有EXISTS谓词的子查询

exists谓词代表存在量词。带有exists谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。可以利用exists来判断 属性与关系表之间的属于关系,关
系表之间的包含、相等关系,关系表之间是否存在交集。

话不多说,第一眼我也没看懂,来个例子看下也许就明白了。

例如,查询所有选修了 1 号课程的学生姓名。

思路:在Student中依次取每个元组的Sno值,用此值去检查 SC 表。若SC中存在这样的元组,其Sno值等于此Student.Sno值,并且其 Cno=‘1’,则取此Student.Sname送入结果表。SQL 语句是

select Sname
from Student
where exists
            (select *
            from SC
            where Sno=Student.Sno and Cno='1');

使用存在量词EXISTS后,若内层查询结果非空,则外层的WHERE 子句返回真值,否则返回假值。

3.4.4 集合查询

SELECT 语句的查询结果是元组的集合,所以多个SELECT 语句的结果可进行集合操作。集合操作主要包括并操作UNION、交操作 INTERSECT 和差操作 EXCEPT

这一小节非常有意思,主要就是集合的并集,交集,差集三个语法,能看到我的文章的同学一定知道数学里的三种意思。

话不多说,看个实例,查询计算机科学系的学生性别为男的学生。

首先我们要查找两个集合
一性别为男的集合

select * from Student where Ssex = '男'

二计算机科学系的学生

select * from Student where Sdept = '计算机科学系'

之后我们用 INTERSECT进行合并

select * from Student 
where Ssex = '男'
intersect
select * from Student 
where Sdept = '计算机科学系'

这样我们就能查到计算机科学系的学生性别为男的学生了。
结果为:

在这里插入图片描述

3.4.5 基于派生表的查询

子查询不仅可以出现在WHERE子句中,还可以出现在 FROM 子句中,这时子查询生成的临时派生素(derived table)成为主查询的查询对象。大眼一看我也不懂。举例我们分析一下

例如,找出每个学生超过他自己选修课程平均成绩的课程号。

SQL语句为:

select Sno,Cno 
from SC,(select Sno,avg(Grade) from SC group by Sno)
                        as Avg_sc(avg_sno,avg_grade)
where SC.Sno = Avg_sc.avg_sno and SC.Grade >= Avg_sc.avg_grade

通过 select Sno,avg(Grade) from SC group by Sno 我们可以获得每个学生的学号以及平均成绩并且通过 AS 命名为 Avg_sc。之后主查询将 SC 表与Avg_sc 按学号相等进行连接,选出选修课成绩大于其平均成绩的课程号。

3.5 数据更新

数据更新操作有三种:向表中添加若干行数据、修改表中的数据和删除表中的若干行数据。在SQL中有相应的三类语句。

3.5.1 插入数据

SQL 的数据插入语句 INSERT 通常有两种形式,一种是插入一个元组,另一种是插入子查询结果。后者可以一次插入多个元组。

1.插入元组

插入元组的 INSERT 语句格式为:

insert into<表名>[(<属性列 1>[<属性列 2>]...)]
values(<常量 1>[,<常量 2>]...);

这么看可能不是很懂,再看一个实例你就明白了

例如,将一个新学生元组(学号201215128,姓名:陈东,性别:男,所在系:计科系,年龄:18岁)插入到 Student 表中。

SQL 语句为:

insert 
into Student(Sno,Sname,Ssex,Sdept,Sage)
values('201215128','陈东','男','计科系',18);

2.插入子查询结果

这个设计非常方便,我们可以先从数据库查询一个集合,把这个查询语句当作插入的子查询,这样可以用查询出的结果映射在要插入的属性字段中。

插入子查询结果的 INSERT 语句格式为

insert into<表名>[(<属性列 1>[,<属性列 2>...])
子查询;

例如,对每一个系,求学生的平均年龄,并把结果存入数据库。

SQL语句为:

insert
into Dept_age(Sdept,Avg_age)

select Sdept,AVG(Sage)
from Student
group by Sdept;

3.5.2 修改数据

修改操作又称更新操作。我们用 UPDATE 和 SET 来进行修改操作。

1.修改某一个元组的值

例如,将学生201215121的年龄改为22岁。

update Student
set Sage=22
where Sno='201215121';

2.修改多个元组的值

例如,将所有学生的年龄增加1岁。

update Student
set Sage=Sage+1;

3.带子查询的修改语句

这种修改方式和插入操作一致也是嵌套的方式。

例如,将计算机科学系全体学生的成绩置零。

update SC
set Grade=0
where Sno in
            (select Sno 
            from Student
            where Sdept='计算机科学系');

3.5.3 删除数据

删除操作和插入修改基本相差不多,当然了既然是删除就要更为严谨一点。一般我们用 DELETE语句 进行删除操作,这里强调一点,DELETE 语句删除的是表中的数据,而不是表种的属性(字段)。

1.删除某一个元组的值

例如,删除学号为201215121的学生记录。

delete
from Student
where Sno='201215121';

2.删除多个元组的值

例如,删除所有的学生选课记录

delete
from SC;

这个语句可以使 SC 表成为空表,删除了SC的所有元组。

3.带子查询的删除语句

删除操作当然也可以使用嵌套方法进行指定删除。

例如,删除计算机科学系所有学生的选课记录

delete
from SC 
where Sno in
            (select Sno
            from Student
            where Sdept='计算机科学系');

3.6 空值的处理

空值定义:空值就是“不知道”或“不存在”或“无意义”的值

SQL 语言中允许某些元组的某些属性在一定情况下取空值。一般情况如下:

  • 该属性应该有一个值,但目前不知道它的具体值。例如,某学生的年龄属性,因为学生登记表漏填了,不知道该学生年龄,因此取空值。
  • 该属性不应该有值。例如,缺考学生的成绩为空,因为没有参加考试。
  • 由于某种原因不便于填写。例如一个人的性别不想让别人知道,则取空值。

所以,空值是一个很特殊的值,含有不确定性,对关系运算带来了特殊的问题,需要以下特殊处理方式。

1.空值的产生

例如,向 SC 表插入一个元组,学生号是“201215121”,课程号是“1”,成绩为空。

insert into SC(Sno,Cno,Grade)
values('201215121','1',NULL);

或者在插入的时候不填任何,默认也是空值。

2.空值的判断

判断也给属性的值是否为空值,用 IS NULL 或 IS NOT NULL来表示。

例如,从Student表中找出漏填了数据的学生信息。

select * from Student
where Sname is null or Ssex is null or Sage is null or Sdept is null;

3.空值的约束条件

属性定义(或者域定义)中有 NOT NULL 约束条件的不能取空值,加了 UNIQUE 限制的属性不能取空值,码属性不能取空值。

4.空值的算术运算、比较运算和逻辑运算

空值与另一个值(包括另一个空值)的算术的结果为空值,空值与另一个值(包括另一个空值)的比较运算的结果为UNKNOWN,有了 UNKNOWN 后,传统的逻辑运算中二值(true,false 逻辑就扩展成了三值逻辑。AND、OR、NOT的真值表如表所示,其中T表示true,F就表示 false,U表示 unknown。
在这里插入图片描述

在查询语句中,只有使 WHERE 和 HAVING子句中的选择条件为 TRUE 的元组才被选出作为输出结果。

例如,找出选修 1 号课程的不及格的学生。

select Sno from SC where Grade < 60 AND Cno='1';

选出的学生是那些参加了考试(Grade 属性为非空值)而不及格的学生,不包括的学生。因为前者使条件 Grade<60 的值为 true,后者使条件的值为 UNKNOWN。

3.7 视图

1.视图是什么?

视图(View)并不在数据库中实际存在,而是一种虚拟表,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。即视图就是执行查询语句后所返回的结果集,所以在创建视图的时候,主要就是创建这条SQL查询语句。

2.视图和表什么区别和联系?

参考:https://blog.csdn.net/duoyu779553/article/details/86579296

3.7.1 定义视图

1.建立视图

SQL语言用CREATE VIEW 命令建立视图,其一般格式为

create view <视图名> [(<列名>[,<列名>]...)]
as <子查询>
[with check option];

其中,子查询可以是任意的SELECT语句,是否可以含有 ORDER BY 子句和 DISTINCT 短语,则取决于具体系统的实现。

例如,建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系的学生。

create view IS_Student
AS
SELECT Sno,Sname,Sage
from Student
where Sdept='IS'
with check option;

由于在定义 IS_Student 视图时加上了 WITH CHECK OPTION 子句,以后对该视图进行插入、修改和删除操作时,关系数据库管理系统会自动加上 Sdept='IS’条件。

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

2.删除视图

该语句的格式为:

drop view <视图名> [cascade];

例如,删除刚刚创建的view_emp_dep视图:

drop view view_emp_dep;

3.7.2 查询视图

视图定义后,用户就可以像对基本表一样对视图进行查询了。

例如,在信息系学生的视图中找出年龄小于20岁的学生。

select Sno,Sage
from IS_Student
where Sage<20;

关系数据库管理系统执行对视图的查询时,首先进行有效性检查,检查查询中涉及的表、视图等是否存在。如果存在,则从数据字典中取出视图的定义,把定义中的子查询和用户的查询结合起来,转换成等价的对基本表的查询,然后再执行修正了的查询。这一转换过程称为视图消解(view resolution)

3.7.3 更新视图

更新视图是指通过视图来插入、删除和修改数据。

由于视图是不实际存储数据的虚表,因此对视图的更新最终要转换为对基本表的更新。像查询视图那样,对视图的更新操作也是通过视图消解,转换为对基本表的更新操作。

为防止用户通过视图对数据进行增加、删除、修改时,有意无意地对不属于视图范围内基本表数据进行操作,可在定义视图时加上 WITH CHECK OPTION 子句。这样在视图上增、删、改数据时,关系数据库管理系统会检查视图定义中的条件,若不满足条件拒绝执行该操作

例如,将信息系学生视图IS_Student 中学号为“201215121”的学生姓名改为“刘辰”。

update IS_Student
set Sname='刘辰'
where Sno='201215121';

转换后的更新语句为

update Student
set Sname='刘辰'
where Sno='201215121' and Sdept='IS';

3.7.4 视图的作用

  1. 当一个查询需要频频的作为子查询使用时,视图可以简化代码,直接调用而不是每次都去重复写这个东西。

  2. 系统的数据库管理员需要给他人提供一张表的某两列数据,而不希望他可以看到其他任何数据,这时可以建一个只有这两列数据的视图,然后把视图公布给他。

  3. 课本解释

    • 视图能够简化用户的操作
    • 视图使用户能以多种角度看待同一数据
    • 视图对重构数据库提供了一定程度的逻辑独立性
    • 视图能够对机密数据提供安全保护
    • 适当利用视图可以更清晰地表达查询

练习题

  1. 试述SQL的特点

  2. 说明在DROP TABLE时,RESTRICT和CASCADE的区别。

  3. 有两个关系S(A,B,C,D)和T(C,D,E,F),写出与下列查询等价的SQL表达式;

  4. 什么是基本表?什么是视图?两者的区别和联系是什么?

  5. 试述视图的优点。

  6. 哪类视图是可以更新的?哪类视图是不可更新的?各举一例说明。

  7. 请为三建工程项目建立一个供应情况的视图,包括供应商代码(SNO)、零件代码(PNO)、供应数量(QTY)。针对视图完成下列查询:

    • 找出三建工程项目使用的各种零件代码及其数量;
    • 找出供应商S1的供应情况

总结

SQL 可以分为数据定义、数据查询、数据更新、数据控制四大部分。本章为重点建议多多练习,特别是增删改查实操部分。

练习网站:http://sqlfiddle.com/


创作不易,点个赞吧!
如果需要后续再看点个收藏!
如果对我的文章有兴趣给个关注!
如果有问题,可以关注公众号【了凡银河系】点击联系我私聊。


猜你喜欢

转载自blog.csdn.net/weixin_45765795/article/details/121599080