2020.4.18数据库小结
基本数据类型
数据类型 | 含义 |
---|---|
char(n) | 长度为n的定长字符串 |
varchar(n) | 最大长度为n的变长字符串 |
int | 长整数 |
smallint | 短整数 |
numeric(p,d) | 定点数,由p位数字组成,小数点后有d为数字 |
real | 取决于机器精度的浮点数 |
double precision | 取决于机器双精度的浮点数 |
float(n) | 浮点数,精度至少为n位数字 |
date | 日期,YYYY-MM-DD |
Time | 时间,HH:MM:SS |
SQL的数据定义功能:模式定义、表定义、视图和索引的定义
- 操作对象 操作方式
|操作对象|创作|删除|修改|
|------------|---------------------|-------------------------|-------------------------|
|数据库|create database|drop database| |
|模式|create schema|drop schema | |
|表|create table | drop table|alter table|
|视图|create view | drop view||
|索引|create index|drop index||
常用完整性约束
- 主码约束: primary key
- 唯一性约束: unique
- 非空值约束:not null
- 参照完整性约束:foreign key
创建下列数据表
--建立学生表Student
create table student(
sno char(9) primary key,
sname varchar(20) unique,
ssex char(2),
sage smallint,
sdept char(20)
);
-- 建立一个课程表course
create table course(
cno char(4) primary key ,
cname char(40),
cpno char(4), /*先修课*/
ccredit smallint,
foreign key(cpno) references course(Cno)
);
-- 建立一个学生选课表sc
create table sc(
sno char(9),
cno char(4),
grade smallint,
primary key (sno,cno),
foreign key (sno) references student(sno),
foreign key (cno) references course(cno),
);
--插入数据
insert student values ('201215121','李勇','男',20,'CS');
insert student values ('201215122','刘晨','女',19,'CS');
insert student values ('201215123','王敏','女',18,'MA');
insert student values ('201215125','张立','男',19,'IS');
insert course values('1','数据库','5',4);
insert course values('2','数学',null,2);
insert course values('3','信息系统','1',4);
insert course values('4','操作系统','6',3);
insert course values('5','数据结构','7',4);
insert course values('6','数据处理',null,2);
insert course values('7','PASCAL语言','6',4);
insert sc values('201215121','1',92);
insert sc values('201215121','2',85);
insert sc values('201215121','3',88);
insert sc values('201215122','2',90);
insert sc values('201215122','1',80);
修改基本表
- add 子句:增加新列和新的完整性约束条件
- drop子句:删除指定的完整性约束条件
- alter column子句:用于修改列名和数据类型
完成下面练习:
--将年龄的数据类型由字符型(假设原来的数据类型是字符型)改为整数
alter table student alter column sage int;
-- 增加课程名必须取唯一值
alter table course add unique (cname);
删除基本表
- drop table <表名> [restrict | cascade]
- restrict :删除表有限制的(如果存在依赖该表的表,则此表不能被删除)
- cascade: 强制删除(并且与该表有关系的表会一并删除。视图也会被删除)
索引
为学生-课程数据库中的Student,Course,SC三个表建立索引。其中Student表按学号升序建唯一索引,Course表按课程号升序建唯一索引,SC表按学号升序和课程号降序建唯一索引。
create unique index stusno on student(sno);
create unique index coucno on course(cno);
create unique index scno on sc(sno asc,cno desc);
-- 删除索引
/*删除索引时,系统会从数据字典中删除有关该索引的描述*/
drop index student.stusno;
查询语句
子句功能
- select 与 from 是必选子句
- select 列出查询的结果
- from 指明所访问的对象
- where 指定查询条件
- group by 将查询结果按指定字段的取值
- having 筛选出满足指定条件的组
- order by 按指定的字段值,以升序或降序排序查询结果
-- 查询全体学生的学号、姓名、所在系
select sno,sname,sdept from student;
--查询全体学生的详细纪律
select * from student;
--查询全体学生的姓名、出生年份
select sname,2020-sage '出生年份' from student;
--在每个学生的姓名后面显示字符串 2017
select sname+'2017' from student;
--查询全体学生的人数
select count(*) from student;
--取消重复行
--查询选修了课程的学生的学号
select distinct sno from sc;
查询满足条件的元组(where )
--取消重复行
--查询选修了课程的学生的学号
select distinct sno from sc;
--查询所有年龄在20岁以下的学生姓名及其年龄。
select sname,sage from student where sage<20;
-- 查询性别为女的学生的学号、姓名
select sno,sname from student where ssex='女';
-- 查询学分为4学分的课程的名字
select cname from course where ccredit=4;
-- 查询成绩在85分以上的学生的学号
select distinct sno from sc where grade>85;
-- 确定范围
--查询年龄在19~21岁(包括19岁和21岁)之间的学生的姓名、系别和年龄
select sname,sdept,sage from student where sage between 19 and 21;
字符串匹配
- 我认为就是判断条件(like + “%”|“_”)
- 当用户要查询的字符串本身就含有 % 或 _ 时,要使用ESCAPE ‘<换码字符>’ 短语对通配符进行转义
-- 查询所有姓刘学生的姓名、学号和性别。
select sname,sno,ssex from student where sname like '刘%';
-- 查询姓“欧阳”且全名为三个汉字的学生的姓名。
select sname from student where sname like '欧阳_';
-- 查询DB_Design课程的课程号和学分。
select cno,ccredit from course where cname like'DB\_Design' escape'\';
-- 查询以“DB_”开头,且倒数第3个字符为 i的课程的详细情况
select * from course where cname like'DB\_%i__' escape'\';
Order by 子句
- 使用order by 子句
-
- 可以按一个或多个属性列排序
-
- 升序asc 降序 desc ;(默认值为升序)
- 当排序列含有空值时
-
- asc: 排序列为空值的元组最后显示
-
- desc: 排序列为空值的元组最先显示
- 当按多个属性排序时:
-
- 首先根据第一个属性排序,如果在该属性上有多个相同的值时,则按第二个属性排序,以此类推
-- 查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列
select sno,grade from sc where cno='3' order by grade desc;
-- 查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列。
select * from student order by sdept asc,sage desc;
主要聚集函数
名称 | 参数类型(列名) | 结果类型 | 描述 |
---|---|---|---|
count | r任意或* | 数值 | 计数 |
sum | 数值型 | 数值 | 计算总和 |
avg | 数值型 | 数值 | 计算平均值 |
max | 数值型、字符型 | 同参数类型一样 | 求最大值 |
min | 数值型、字符型 | 同参数类型一样 | 求最小值 |
- distinct:在计算是要取消指定列中的重复值
- all短语:缺省值,不取消重复值
对查询结果分组
-- 求各个课程号及相应的选课人数
select cno,count(sno) from sc group by cno;
-- 查询选修了3门以上课程的学生学号
select sno from sc group by sno having count(*)>3;
连接
自身连接
- 一个表与其自己进行连接,称为表的自身连接,需要给表起别名以示区别,由于所有属性名都是同名属性,因此必须使用别名前缀
外连接(Outer Join)
- 外连接操作以指定表为连接主体,将主体表中不满足连接条件的元组一并输出
外连接小结
- 左外连接
-
- 左外连接为left outer join
-
- 列出左边关系中的所有元组
- 右外连接
-
- 右外连接符为right outer join
-
- 列出右边关系中所有元组
- 外连接
-
- 外连接符为full outer join
-
- 列出左右两边关系中所有的元组
嵌套查询
- 自己感觉嵌套查询就是把简单查询堆积起来就是嵌套查询啦(一方面为了节省时间,就不重点展开了)
- 将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询
嵌套查询分类
- 不相关子查询
-
- 子查询条件不依赖父查询
- 相关子查询
-
- 子查询的查询条件依赖父查询
- 子查询的查询条件依赖父查询
带有any 或all谓词的子查询
- any : 任意一个值
- all: 所有值
- 需要配合使用运算符
exists谓词的子查询
- 存在量词
- 带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。
-
- 若内层查询结果非空,则外层的WHERE子句返回真值
-
- 若内层查询结果为空,则外层的WHERE子句返回假值`
--查询所有选修了1号课程的学生姓名。
select sname from student where exists
(
select * from sc where student.sno=sc.sno and cno=1
)
用EXISTS/NOT EXISTS实现全称量词(难点)
- SQL语言中没有全称量词 (For all)
- 可以把带有全称量词的谓词转换为等价的带有存在量词的谓词:
--查询选修了全部课程的学生姓名
select sname from student where not exists
(
select * from course where not exists
(
select * from sc where sno=student.sno and cno =course.cno
)
);
集合查询
- 并操作(union)
- 交操作(intersect)
- 差操作(minus)
-- 插入语句
insert into student values ('201215126','张加民','男',18,'CS');
数据的修改
-
修改某个元组的值
-
修改多个元组的值
-
带子查询的修改语句
--将学生201215121的年龄改为22岁
update student set sage=22 where sno='201215121';
-- 将所有学生的年龄增加一岁
update student set Sage=sage+1;
-- 将计算机科学系(MA)全体学生的成绩置零
--insert into sc values ('201215123','1',63);
update sc set grade=0 where sno in
(
select sno from student where sdept='MA'
);
数据删除
- 删除某一个元组的值
- 删除多个元组的值
- 带子查询的删除语句
--删除学号为201215128的学生记录
delete from student where sno='201215128';
--删除所有学生的选课记录
delete from sc;
-- 删除计算机科学系的所有学生的选课记录
delete from sc where 'CS' =
(
select sdept from student
where student.sno=sc.sno
)
视图
- 定义视图
- 删除视图
--建立信息系学生的视图
create view IS_Student as
select sno,sname,sage from student where sdept='IS' with check option ;
-- 建立信息系选修了1号课程的学生视图
create view C_1 as
select sc.sno,sname,sage,grade from student,sc where student.sno=sc.sno and cno='1';
-- 建立信息系选修了1号课程且成绩在90分以上的学生视图。
create view c_1_90 as
select * from C_1 where grade>90;
--将学生的学号及他的平均成绩定义为一个视图。
create view s_avg_grade (sno,avg_score) as
select sno,avg(grade) from sc group by sno;
删除视图
- 查询视图跟正常使用select语句一样(我感觉把它当成一张表就行)
- 更新视图
视图的作用
- 视图能够简化用户的操作
- 视图使用户能以多种角度看待同一数据
- 视图对重构数据库提供了一定程度的逻辑独立性
- 视图能够对机密数据提供安全保护
- 适当的利用视图可以更清晰的表达查询