《数据库系统概论》SQL语言篇 (第5版 王珊 萨师煊 编著)

结构化查询语言SQL是关系数据库的标准语言,也是一个通用的、功能极强的关系数据库语言。常见的关系数据库如MySql 、SQL Server、Oracle等都使用了SQL语法,学习SQL对掌握常见数据库有很大帮助。

#主要内容

1、模式的定义与删除
2、表的创建、修改和删除
3、索引的创建和删除
4、数据查询
5、数据更新(插入、更新、删除)
6、视图
7、授权

语法符号含义:

  1. <> 必选内容
  2. [] 可选内容
  3. | 多选一

一、模式的定义与删除

1、创建模式

create schema <模式名> authorization <用户名>;

没有指定模式名,则模式名隐含为用户名。创建模式时该用户需要有权限。
例题:为用户WANG创建一个模式S-T。

  1. create schema “S-T” authorization WANG;

  2. create schema authorization WANG;
    没有指明模式名,隐含为用户名WANG。

2、删除模式

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

cascade:级联删除,删除模式的同时删除该模式的所有数据库对象。
restrict:限制删除,如果该模式定义了表、视图等下属对象,则拒绝执行该条删除语句。

3、创建模式时可以同时创建模式下属的表、视图和进行授权

create schema <模式名> authorization <用户名> [<表创建语句> | <视图创建语句> | <授权语句>]

例题:为用户WANG创建一个 TEST 模式,并且在模式中创建一个表TAB。

create schema TEST authorization WANG
create table TAB(
column1 int,
column2 char(20)
);

二、表的创建、修改和删除

1、表的常见数据类型

  1. char(n) :长度为n的定长字符串。
  2. varchar(n) :最大长度为n的变长字符串。
  3. smallint :短整数,2字节
  4. int :长整数,4字节。
  5. float(n) :可选精度的浮点数,精度至少为n位数。
  6. numeric(p,d) :定点数,由 p 位数组成(不包括符号、小数点),小数点后有 d 位数字。
  7. boolean :布尔类型。
  8. date :日期,格式为 年-月-日(YYYY-MM-DD)。
  9. time :时间,格式为 时-分-秒(HH:MM:SS)。

2、表的常见列级完整性约束条件

  1. not null :列值不为空。
  2. unique :列值唯一,如学生学号。
  3. check (语句) :列值要满足相应条件,如性别只能选男/女。
  4. primary key :列值为主码。

3、表的常见表级完整性约束条件

  1. primary key( 列1,列2,…,列n ):主码由列 1 至列 n 组成。
  2. foreign key (列名) references <参照的表名>(列名):外码参照了某表。

4、创建表

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

[,<表级约束条件> ]
);

例题:创建学生选课表SC

create table SC
( Sno char(9),
Cno char(4),
Ssex char(2),
Grade int,
primary key (Sno,Cno),
foreign key(Sno) references Student(Sno),
foreign key(Cno) references Course(Cno)
);

create table SC
( Sno char(9) unique,
Cno char(4) unique not null,
Ssex char(2) check (Ssex in(‘男’,‘女’) ),
Grade samllint check (Grade >= 0 and Grade <= 100),
foreign key(Sno) references Student(Sno),
foreign key(Cno) references Course(Cno)
);

该表约束说明:

  1. Sno 列值要唯一,
  2. Cno 列值唯一且值不为空,
  3. Ssex 性别只能是男或女,
  4. Grade 成绩只能在 0-100 范围取值,
  5. Sno 和 Cno 共同组成了表的主码,
  6. Sno 作为外码参照了 Student表,
  7. Cno 作为外码参照了 Course 表。

5、修改表

alter table <表名>
[ add [column] <新列名> <数据类型> [完整性约束条件] ]
[ add <表级约束条件> ]
[ drop [column] <列名> [ cascade | restrict ] ]
[ drop constraint <完整性约束名> [ cascade | restrict ] ]
[ alter column <列名> <数据类型> ];

分别对应 加列、加约束条件、删列、删约束条件、修改列。

例题

  1. alter table Student add Sage int; 向表Student添加年龄,数据类型是int
  2. alter table Student alter column Sage smallint; 将年龄列类型改为smallint
  3. alter table Course add unique(Cname); 添加约束条件

6、删除表

drop table <表名> [ restrict | cascade];

例题:

drop table Student cascade;

三、索引的创建和删除

索引简介:为表提供多种存取路径,加快查找速度。常见索引类型有顺序文件上的索引、B+树索引、散列索引、位图索引等,在执行查询时系统会自动选择合适的索引作为存取路径,用户不必也不能显式地选择索引。索引是关系数据库管理系统的内部实现技术,属于内模式的范畴。

  1. 建立索引能加快查询速度。
  2. 一个表上可以有多个索引。
  3. 表更新时,索引要进行维护,这会增加数据库负担,所以索引不能太多。

1、建立索引

create [unique] [cluster] index <索引名>
on <表名> (<列名> [<排序方式>] [,(<列名> [<排序方式>] …]);

unique:表示索引的每个值只对应唯一的数据记录。
cluster :表示该索引是聚簇索引。
排序方式:ASC (升序),DESC(降序)
聚簇索引:把一些元组集中存放在连续的物流块中,能显著减少访问磁盘的次数。一个数据库可以建立多个聚簇,一个关系只能加入一个聚簇。建立与维护聚簇的开销相关大。

例题:

  1. create unique index Stusno on Student (Sno);
  2. create unique index SCno on SC ( Sno ASC , Cno DESC);

2、修改索引

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

3、删除索引

drop index <索引名>;

四、数据查询

数据字典:关系数据库管理系统内部的一组系统表,记录了数据库中所有的定义信息,包括模式定义、视图定义、索引定义、完整性约束定义、各类用户对数据库的操作权限、统计信息等。在执行SQL的数据定义语句时,实际上就是在更新数据字典中的相应信息

1、查询语法
select [all | distinct ] <目标列表达式> [,<目标列表达式> ] …
from <表名或视图名> [,<表名或视图名>] …
[ where <条件表达式>]
[ group by <列名> [having <条件表达式> ] ]
[ order by <列名> [ASC | DESC ]];

all是默认值(可不写),distinct 值表示取消指定列的重复值。
目标列表达式可以是属性列、算术表达式、字符串常量、函数等。
group by :是指按列分组,列值一样的分到一组,如果有having语句还要满足该having条件。
order by :是指结果按列值排序。

2、where子句常用查询条件

  1. 比较:= , > , < , >= , <= , != , <>(不等于), !> , !< ; not + 上述比较运算符。
  2. 确定范围:between x and y ,not between x and y。
  3. 确定集合:in , not in。
  4. 字符匹配:like , not like 。
  5. 空值:is null , is not null 。
  6. 多重条件:and , or , not 。
  7. 比较运算符 + ANY或者ALL

like字符匹配:’’ % ‘‘代表任意长度;’’ _ ''代表单一字符。

3、聚集函数

聚集函数不能当where的子句条件,having和select里都可以用。

  1. COUNT( * ) :统计元组个数,“ * ”表示元组。
  2. COUNT( [distinct | all] <列名>) :统计一列的个数。
  3. SUM( [distinct | all] <列名>) :计算一列值的总和。
  4. AVG( [distinct | all] <列名>) :计算一列值的平均值。
  5. MAX( [distinct | all] <列名>) :求一列值中的最大值。
  6. MIN( [distinct | all] <列名>) :求一列值中的最小值。

4、单表查询例题

  1. 查询全体学生的姓名、学号
    select Sname,Sno
    from Student;

  2. 查询全部列(查询元组)
    select *
    from Student;

  3. 查询全体学生姓名及其出生年份,下面的birthday是定义的别名
    select Sname,2020-Sage birthday
    from Student;

  4. 消除重复行
    select distinct Sno
    from Student;

  5. 查询软件学院的全部学生姓名
    select Sname
    from Student
    where Sdept = ‘软件学院’

  6. 查询所有年龄在20岁以下的学生姓名及其年龄
    select Sname,Sage
    from Student
    where Sage < 20;

  7. 查询所有年龄在20岁到23岁的学生姓名和年龄
    select Sname,Sage
    from Student
    where Sage between 20 and 23;

  8. 查询所有在计算机系(CS)、数学系(MA)学生的姓名和年龄
    select Sname,Sage
    from Student
    where Sdept in (‘CS’,‘MA’);

  9. 查询所有第2个字为“阳”且年龄是20岁的学生的姓名、学号
    select Sname,Sno
    from Student
    where Sname like ‘_阳%’ and Sage = 20 ;

  10. 查询年龄是20岁的学生的人数
    select COUNT(Sage)
    from Student
    where Sage = 20;

  11. 查询各个课程号及其选修人数
    select Cno,COUNT(Sno)
    from SC
    group by Cno;

  12. 查询选修了三门以上学科的学生学号
    select Sno
    from SC
    group by Sno
    having COUNT(*) > 3
    ;

5、连接查询例题

  1. 简单连接:查询选修2号课程且成绩在90分以上的所有学生的学号和姓名
    select Student.Sno,Sname
    from Student,SC
    where Student.Sno = SC.Sno
    and SC.Cno = ‘2’ and SC.Grade > 90;

  2. 自身连接:为一表取多个别名,如FIRST,SECOND;查询每一门课先修课的先修课。
    select FIRST.Cno,SECOND.Cpno
    from Course.FIRST,Course.SECOND
    where FIRST.Cpno = SECOND.Cno;

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

6、嵌套查询

一个select-from-where 语句称为一个查询块,在where 和having子句里嵌套一个查询块称为嵌套查询,可多级嵌套。

  1. 谓词 in 的子查询
    select Sname
    from Student
    where Sno in
    (select Sno
    from SC
    where Cno = ‘2’);

    where 子句里的列名和嵌套里select子句里的列名要一样(Sno对应Sno)

  2. 带有ANY/ALL谓词的子查询
    select Sname,Sage
    from Student
    where Sage < ANY( select Sage
    from Student
    where Sdept = ‘CS’)
    and Sdept <> ‘CS’;

  3. 带有EXISTS谓词的子查询,该类查询不返回数据,只产生逻辑真“true”和假“false”,目标表达式通常用 “ * “,因为给出列名无意义。
    select Sname
    from Student
    where EXISTS
    (select *
    from SC
    where Sno = Student.Sno and Cno = ‘1’);

7、派生查询

自己先构造个派生表并给表一个别名,然后使用该表。
select Sname
from Student,(select Sno from SC where Cno=‘1’) AS SC1
where Student.Sno = SC1.Sno;

五、数据更新

1、插入数据
insert into <表名> [(<属性列1> [,<属性列2> ] …)]
values (<常量1> [,<常量2>] …)
[子查询];

例题: 插入一个新学生的元组

insert into Student(Sno,Sname,Ssex,Sdept,Sage)
values (‘100001’,‘陈冬’,‘男’,‘IS’,18);

2、修改数据

update <表名>
set <列名> = <表达式> [,<列名> = <表达式>] …
[ where <条件>];

例题

update Student
set Sage = 22
where Sno = ‘100002’;

update Student
set Sage = Sage +1;

updte SC
set Grade = 0
where Sno in
(select Sno
from Student
where Sdept = ‘CS’);

3、删除数据

delete from <表名>
[ where <条件>];

delete from Student
where Sno = ‘100001’;

delete from SC;

delete from SC
where Sno in
(select Sno
from Student
where Sdept = ‘CS’);

六、视图

视图是从一个或多个基本表中导出的表,视图是一个虚表,数据库中只存放视图的定义,视图中的数据仍然存储在原来的基本表中。一旦基本表数据发生变化,从视图查询到的数据也会随之变化。可以在视图上再创建一个视图。

视图的作用:

  1. 简化用户操作,因为能将表与表间的连接操作对用户隐蔽了。
  2. 能使用户以多个角度看待同一个数据,为不同类型的用户共享数据提供便利。
  3. 对重构数据库提供一定的逻辑独立性。

1、创建视图

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

create view 语句只是把视图定义存到数据字典,而不执行实际的select操作。
with check option 表示对视图进行update、insert、delete操作时要保证操作的行满足视图定义的子查询中的条件表达式

例题:

  1. create view IS_Student
    AS
    select Sno,Sname,Sage
    from Student
    where Sdept = ‘IS’
    with check option;
  2. create view IS_S1( Sno,Sname,Grade)
    AS
    select Student.Sno,Sname,Grade
    from Student,SC
    where Sdept = ‘TS’ and
    SC.Cno = ‘1’ and Student.Sno = SC.Sno;
  3. Sbirth是2020-Sage的别名,2020-Sage可以用聚集函数替代。
    create view BT_S(Sno,Sname,Sbirth)
    AS
    select Sno,Sname,2020-Sage
    from Student;

2、删除视图

drop view <视图名> [ cascade ] ;

删除视图是删除视图的定义,因为视图是虚表。

3、查询视图

查询语法与表查询一致

视图查询是将视图查询转换成对基本表的查询。这一转换过程叫做视图消解。

如:在信息系学生的视图中找出所有年龄小于20岁的学生学号、年龄。
select Sno,Sage
from IS_Student
where Sage < 20;
等价于
select Sno,Sage
from Student
where Sdept = ‘IS’ and Sage < 20;

4、更新视图

更新语法与表一致

因为视图是虚表,对视图的更新最后会转换为对基本表的更新。为了防止用户通过视图对数据操作,对不属于视图范围的表进行操作,可以在创建视图时加上with check option子句。

七、授权

SQL提供grant 和 revoke 语句向用户授予或收回数据库操作权限。不能循环授权。all privileges 表示全部操作权限。

1、用户和角色的创建

创建用户:
create user <用户名> [ with ] [ DBA | RESOURCE | CONNECT];

系统的超级用户才有权创建一个新的用户。用户在创建时有三种权限,默认是connect,connect权限只能登录数据库;resource权限能创建表、视图但不能创建模式和新建用户;拥有DBA权限的用户是超级用户。

创建角色:(角色是权限的集合
create role <角色名>;

2、grant

grant <权限> [, <权限>] …
on <对象类型> <对象名> [, <对象类型> <对象名>]…
to <用户|角色> [ ,<用户|角色>]…
[ with check option] ;

with check option 表示获得某种权限的用户可以把这种权限再授予其他用户。没有该语句则不能传播获得的权限。

例题:

  1. 把查询Student表的权限授予用户U1.
    grant select
    on table Student
    to U1;

  2. 将对表Student和Course的所有操作权限授予用户U2 和U3.
    grant all privileges
    on table Student,Course
    to U1,U2;

  3. 把查询Student表和修改学生学号的权限授予用户U1.
    grant update(Sno),select
    on table Student
    to U1;

3、revoke

revoke <权限> [,<权限> ] …
on <对象类型> <对象名> [, <对象类型> <对象名>]…
from <用户|角色> [,<用户|角色>] … [ cascade | restrict];

cascade 表示收回某个用户的权限时,同时收回这个用户传播出去的授权。

例题:

  1. 收回所有用户对表SC的查询权限,public 表示所有用户
    revoke select
    on table SC
    from public

  2. 把用户U1对SC表的insert 权限收回,级联方式。
    revoke insert
    on table SC
    from U1 cascade;

4、强制存取控制和自主存取控制

强制存取控制:每一个数据库对象都被标以一定的密级,每一个用户也被授予某一个级别的许可证。强制存取控制是对数据本身进行密级的标记,无论数据如何复制,标记和数据是一个不可分的整体。存取规则:
(1)仅当主体的许可证级别大于或等于客体的密级时,该主体才能读取相应的客体。
(2)仅当主体的许可证级别小于或等于客体的密级时,该主体才能相应的客体。
规则(2)是为了防止数据密级从高流向低。

自主存取控制:用户对不同的数据库对象有不同的存取权限,不同的用户对同一对象也有不同的权限,且用户可以传播自己的权限给其他用户。简单点说,不是强制存取控制的差不多就是自主存取控制。

触发器和游标就是应用相关了,就不讲了

猜你喜欢

转载自blog.csdn.net/qq_44829047/article/details/107254468