1、SQL
Structured Query Language,即结构化查询语言。 是关系数据库的标准语言。
2、sql对关系数据库模式的支持
3、数据定义
1、SQL 的数据定义语句
SQL 不提供修改模式定义、修改视图定义和修改索引定义的操作,若想修改需先删掉再重建。
2、模式的定义与删除
a、定义模式
create schema authorization ;
如果没有指定 模式名,隐含为 用户名。
实例:
在 mysql 中定义模式(即创建数据库)语句为:
creater schema wtf;
/*或者使用:*/
creater database wtf; /*常用*/
b、删除模式
drop schema ;
其中 cascade(级联)表示删除数据库及其中所有对象一起删除,restrict(限制)只有数据库中没有对象时才能删除。
实例:
在 mysql 中 删除数据库语句为:(mysql是直接删除整个数据库,相当于 cascade)
drop schema wtf;
/*或者使用: */
drop database wtf; /*常用*/
3、定义基本表
建表的同时通常还可以定义与该表有关的完整性约束条件,如
primary key 指示为主键,unique 指示取唯一值,not null 指示为非空。还可以指定外码如:
create table sc(
sno char(7),
cno char(4),
grade smallint,
primary key(sno,cno),/*主码*/
foreign key (sno) references student(sno),
/*表级完整性约束条件,标明外码及其被参照表*/
foreign key (cno) references course(cno)
);
4、SQL 数据类型
要注意,不同的 RDBMS 中支持的数据类型不完全相同
SQL主要数据类型如下:
数据类型
含义
char(n)
长度为 n 的定长字符串
varchar(n)
最大长度为 n 的变长字符串
int
长整数(也可写作 integer)
smallint
短整数
numeric(p,d)
定点数,由 p 位数字(不包括符号、小数点)组成,小数点后面有 d 位数字
real
取决于机器精度的浮点数
double precision
取决于机器精度的双精度浮点数
float(n)
浮点数,精度至少为 n 位数字
date
日期, 包含年月日,格式为 YYYY-MM-DD
time
时间,包含时分秒,格式为 HH:MM:SS
5、模式与表
每一个基本表都属于某一个模式,一个模式包含多个基本表
定义基本表时,定义它所属的模式的方法如下:
a、在表名中明显的给出模式名
如:create table "S-T".student(......);
b、在创建模式语句中同时创建表
c、设置所属模式
如:设置搜索路径: set search_path to "S-T",public;
在 mysql 中可以使用: use 数据库名; 来指定使用哪个数据库
6、修改基本表
alter table
[ add [完整性约束] ]
[ drop ]
[ alter column ];
实例:
alter table student add sage int;
alter table student alter column sage smallint;
mysql 中:
7、删除表
drop table < 表名 > [ cascade | restrict ];
mysql 中 则直接删除整个表数据,相当于 cascade
8、建立索引
建立索引是加快查询速度的有效手段,用户可以根据应用环境的需要,在基本表上建立一个或多个索引
以提供多种存取路径,加快查找速度。
create [ unique ] [ cluster ] index
on ( [ ] [, [ ] ]...);
实例:
其中次序可选 asc(升序,缺省值),desc(降序),unique 表明此索引的每一个索引值只对应唯一的数据记录,
cluster 表示要建立的索引是聚簇索引,所谓聚簇索引是指索引项的顺序与表中记录的物理顺序一致的索引组织。
9、删除索引
drop index ;
建立索引是为了减少查询操作的时间,但如果数据增删改频繁,系统会花费许多时间来维护索引,从而降低了查询效率。
删除索引表时,系统会同时从数据字典中删去有关该索引的描述。
4、数据更新
1、插入数据
a、插入元组
insert into [ ( [, ] ... ) ]
values ( [, ] ... );
其功能是将新元组插入指定表中,属性列与常量列依次对应,没有出现的属性列将取空值,但 not null 的属性列不能取空值。
如果 into 子句中没有指名任何属性列名,则新插入的元组必须在每个属性列上均有值。
实例:
b、插入子查询结果
insert
into [ ( [, ] ... ) ]
子查询;
实例:
insert
into dept_age(sdept, avg_age)
select sdept,avg(sage)
from student
group by sdept;
2、修改数据
修改数据又称更新操作,一般格式为
update
set = [, < 列名> = < 表达式 > ]...
[ where ];
其功能是修改指定表中满足 where 子句条件的元组,其中 set 子句给出 表达式 的值用于取代相应的属性列值,
若省略 where 子句,则表示修改表中所有元组
实例:
a、修改某一元组的值
b、修改多个元组的值
update student
set sage = sage + 1;
c、带子查询的修改语句
update sc
set grade = 0
where 'cs' =
(select sdept
from student
where student.sno = sc.sno);
3、删除数据
delete
from < 表名 >
[ where ];
若省略 where 子句,表示删除表中全部元组,但表的定义仍存在。
可以删除某一个元组的值,可以删除多个元组的值,还可以使用带子查询的删除语句。
实例:
5、数据查询
一般格式:
select [ all | distinct ] [ , ] ...
from [, ] ...
[ where ]
[ group by [ having ] ]
[ order by [ asc | desc ] ];
即根据 where 子句的条件表达式,从 from 子句指定的基本表或视图中找出满足条件的元组,再按 select 子句的目标表达式,
选出元组中属性值形成果表,如果有 gruop by 子句,则将结果按 的值进行分组,该属性列值相等的元组为一个组,
通常会在每组中作用聚集函数,如果子句带 having 短语,则只有满足条件的组才予以输出。order by 使结果表按 排序。
1、单表查询
(1)选中表中若干列
a、查询指定列
b、查询全部列
c、查询经过计算的值
(2)选中表中的若干元组
a、取消取值重复的行(使用 distinct 关键字)
b、查询满足条件的元组
常用的查询条件:
查询条件
谓词
比较
= , > , < , >= , <= , != , <>(不等于) , !> , !< ; not + 上诉比较运算符
确定范围
between and , not between and
确定集合
in , not in
字符匹配
like , not like
空值
is null , is not null
多重条件(逻辑运算)
and , or , not
字符匹配:
谓词 like 可以用来进行字符串的匹配,语法格式为:
[ not ] lile '' [ escape '' ]
其含义是查找指定的属性列值 与 相匹配的元组。
可以是含有通配符 %(任意长度字符) 和 _ (任意单个字符)
实例:查询以 "DB_" 开头,且倒数第3个字符为 i 的课程的详细情况
select *
from course
where cname like 'DB_%i__' escape '';
这里的第一个 "_ " 前面有转码字符 , 被转义为普通字符, escape '' 表示 "" 为转码字符
注意在 mysql 里,转码字符 被写成 /
(3)order by 子句
用此子句对查询结果按照一个或多个属性列的升序(asc,缺省值)或降序(desc)排列。
(4)聚集函数
为增强检索功能,SQL 提供许多聚集函数,主要有:
count( [ distinct | all ] * )
统计元组个数(distinct 表示去除重复值,缺省为 all)
count( [ distinct | all ] < 列名 > )
统计一列中值的个数
sum( [ distinct | all ] < 列名 > )
计算一列值的总和(此列必须是数值型)
avg( [ distinct | all ] < 列名 > )
计算一列值的平均值(此列必须是数值型)
max( [ distinct | all ] < 列名 > )
求一列值中的最大值
mix( [ distinct | all ] < 列名 > )
求一列值中的最小值
(5)group by 子句
group by 子句将要查询结果按某一列或多列的值分组,值相等的为一组。
实例:对查询结果按 cno 的值分组,所有具有相同 cno 值的元组为一组,然后用 count 计算该组的人数
2、连接查询
若一个查询同时涉及两个以上的表,则称之为连接查询。
(1)等值与非等值连接查询
[ . ] < 列名 1 > < 比较运算符 > [ < 表名 2> . ] < 列名 2 >
其中比较运算符:等值连接: = , 非等值连接:> , < ,>= , <= , != , <> 等
也可以使用:
[ . ] < 列名 1 > between [ < 表名 2> . ] < 列名 2 > and [ < 表名 2> . ] < 列名 3 >
实例:查询 信息系 的年龄在21岁及以下的男生姓名及其年龄
(2)自身连接
连接操作不仅可以在两个表之间进行,也可以是一个表与其自己进行连接,称为表的自身连接。
实例:查询每一门课的间接先修课(即先修课的先修课)
在 course 中 cpno 为 该课程 cno 的先修课程,要查询先修课的先修课,必须对一门课找到
其先修课,再按此先修课的课程号,查找它的先修课程。为此要为 course 表取两个别名,first 和 second :
(3)外连接
在通常的连接操作中只有满足连接条件的元组才能作为结果输出,如下图,学生 小明没有选课,但仍想
把舍弃的 小明 元组保存在结果关系中,而在 sc 表的属性上填空值就需要使用外连接。
左连接:student 表包容 sc 表,左连接左表是全的,列出左边关系中所有元组, SQL 语句为:
select student.sno,sname,sex,deptno,sage,cno,grade
from student left out join sc on(student.sno=sc.sno);
/*也可以使用using来去掉重复值
from student left out join sc using(sno);*/
右连接:sc 表包容 student 表,右连接右表是全的,列出右边关系中所有元组
(4)内连接
student 与 sc 两表的交集, inner join 比 left join 快,内连接等价于:
select student.sno,sname,sex,deptno,sage,cno,grade
from student,sc where student.sno=sc.sno;
(5)复合条件连接
where 子句中有多个连接条件称为复合条件连接
下面是一个多表复合条件连接实例:
3、嵌套查询
在 SQL 语言中,一个 select-from-where 语句称为一个查询块,将一个查询块嵌套在另一个查询块的 where 子句
或 having 短语的条件中的查询称为嵌套查询。
(1)带有 in 谓词的子查询
在嵌套查询中,子查询的结果往往是一个集合,使用 谓词 in 如下:
上例中,子查询的查询条件不依赖于父查询,称为不相关子查询。
(2)相关子查询
查找每个学生超过他选修课程平均成绩的课程号及成绩:
x 是 表 sc 的别名,又称元组变量,可以用来表示 sc 的一个元组。内层查询是求一个学生所有选修课课程
平均成绩的,至于是哪个学生的平均成绩要看参数 x.sno 的值,而该值是与父查询相关的,称为相关子查询。
(3)带有 any (some) 或 all 谓词的子查询
实例:查询其他系中比计算机科学与技术系所有学生年龄都小的学生姓名及年龄:
(4)带有 exists 谓词的子查询
exists 代表存在量词 ヨ,带有 exists 谓词的子查询不返回任何数据,只产生逻辑 true 或 逻辑 false。
由于没有全称量词,可以使用 两次 not exists 代替
实例:查询选修了张星老师开设的全部课程的学生姓名
4、集合查询
select 语句的查询结果是元组的集合,所以多个 select 语句的结果可以进行集合操作,包括并操作 union、
交操作 intersect 和差操作 except 。注意 参加集合操作的各查询结果的列数必须相同,对应项的数据类型也必须相同。
实例:查询系号为10以及年龄不大于21的学生,用集合查询,相当于下面的 or 语句,但前者是分别进行两次查询将结果取
并集,而后者是直接进行一次查询。注意: mysql 并不支持 intersect 和 except 集合操作。
6、视图
视图是从一个或几个基本表(或视图)导出的表,是一个虚表,数据库中只存放视图的定义,而不存放视图对应的数据。
视图就像一个窗口,透过它可以看到数据库中自己感兴趣的数据及其变化。其可以有基本表一样被查询、删除,但更新操作有一定的限制
1、建立视图
一般格式:
create view < 视图名 > [ ( < 列名 > [, < 列名> ] ... ) ]
as < 子查询 >
[ with check option ]
其中,子查询可以是任意复杂的 select 语句,但通常不允许包含 order by 子句和 distinct 短语,with check option 表示
对视图进行 update,insert 和 delete 操作时要保证更新、插入或删除的行满足视图定义中的谓词条件(即子查询中的条件表达式)
组成视图的属性列名或者全部省略或者全部指定,但在下列三种情况下必须明确指定组成视图的所有列名:
(1)某个目标列不是单纯的属性名,而是聚集函数或列表达式
(2)多表连接时选出了几个同名列作为视图的字段
(3)需要在视图中为某个列启用新的更合适的名字
视图不仅可以建立在一个或多个基本表上,也可以建立在一个或多个已定义好的视图上,或建立在视图与基本表上。
实例:建立 系号为 10 选修了 1 号课程学时的视图
建立 系号为 10 选修了 1 号课程且成绩在 90 分以上的学生的视图
2、查询视图
实例:查询选修了 1 号课程的 系号为 10 的学生
定义 is_student 视图时 加上了 with check option 子句,以后视图的增删时都会自动加上 deptno=10的条件
3、删除视图
格式为:
drop view < 视图名 > [ cascade ] ;
删除视图后视图的定义将从数据字典中删除,加上 cascade 级联删除后,把该视图和由它导出的所有视图一起删除。
4、更新视图
更新视图最终要转换为对基本表的更新。
实例:
insert
into is_student
values('1007','逃兵',25);
delete
from is_student
where sno=1001;
有些视图是不可更新的,个系统实现有差异。
5、视图的作用
视图最终是定义在基本表之上的,对视图的操作最终也要转换为对基本表的操作,但合理的使用视图能够带来许多好处
(1)视图能够简化用户的操作
视图机制使用户可以将注意力集中在所关心的数据上。
视图可以简化用户操作,还可以将定义若干表的连接操作隐藏起来,使结构简单,清晰。
(2)视图使用户能以多种角度看待同一数据
(3)视图对重构数据库提供了一定程度的逻辑独立性
(4)视图能够对机密数据提供安全保护
(5)适当的利用视图可以更清晰的表达查询
例如:经常需要执行查询“对每个同学找出他获得最高成绩的课程号”,可以先定义一个视图,求出
每个同学获得的最高成绩,然后用查询语句完成查询,如下: