三、SQL
现在就主要是SQL,主要是高效易学还简单。
下面的操作会用到的表
基本数据添加语句
insert into student
(sno, sname, ssex, sage, sdept)
values
(201215121,"李勇","男",20,"CS"),
(201215122,"刘晨","女",19,"CS"),
(201215123,"王敏","女",18,"MA"),
(201215125,"张立","男",19,"IS");
insert into course (Cno, Cname, Cpno, Credit)
values
(1,"数据库",5,4),
(2,"数学",NULL,2),
(3,"信息系统",1,4),
(4,"操作系统",6,3),
(5,"数据结构",7,4),
(6,"数据处理",NULL,2),
(7,"PASCAL语言",6,4);
insert into sc (Sno, Cno, Grade)
values
(201215121,1,92),
(201215121,2,85),
(201215121,3,88),
(201215122,2,90),
(201215122,3,80)
1、数据的定义
1 模式的定义与删除
定义模式
定义模式实际上定义了一个命名空间,一个框架,在这个空间中可以进一步定义该模型包含的数据库对象,例如基本表、视图、索引等。
CREATE SCHEMA <模式名> AUTHORIZATION <用户名>
如果没有指定<模式名>,那么<模式名>隐含为<用户名>
例如:定义一个学生—课程模式S-T
CREATE SCHEMA S-T AUTHORIZATION WANG;
也可以这样
CREATE SCHEMA <模式名> AUTHORIZATION <用户名>[<表定义子句>|<视图定义子句>|<授权定义子句>];
删除模式
DROP SCHEMA <模式名><CASCADE|RESTRICT>
其中CASCADE、RESTRICT两者必选一个。选择CASCADE(级联),表示再删除模式的同时把该模式中所有的数据库对象全部一起删除。选择RESTRICT(限制),表示如果该模式中已经定义了下属的数据库对象,则拒绝执行该删除语句。
例如:
DROP SCHEMA S-T CASCADE;
该语句删除了模式S-T。同时把该模式下的表、视图等删除。
2 基本表的定义、删除与修改
定义基本表
CREATE TABLE <表名> (<列名> <数据类型> [列级约束条件],
<列名> <数据类型> [列级约束条件],
……
[<表级约束条件>]);
举个例子:
/*创建学生表*/
CREATE TABLE Student(
Sno CHAR(9) PRIMARY KET, /*列级完整性约束条件,Sno是主码*/
Sname CHAR(20) UNIQUE, /*Sname去唯一值*/
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20)
)
/*建课程表*/
CREATE TABLE Course(
Cno CHAR(4) PRIMARY KEY,
/*列级完整性约束条件,Cno是主码*/
Cname CHAR(40),
Cpno CHAR(4),
/*Cpno的含义是先修课*/
Credit SMALLINT,
FOREIGN KEY (Cpno) REFERENCES Course(Cno)
/*表级约束性条件,Cpno是外码,被参照表是Course,被参照列是Cno*/
);
/*建选课表*/
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)
)
执行完就这样子
3 修改基本表
ALTER TABLE <表名>
[ADD <新列名><数据类型>[完整性约束]]
[DROP <完整性约束名>]
[ALTER COLUMN <列名> <数据类型>];
添加入学时间列,并且是日期类型
ALTER TABLE student ADD S_entrance DATE;
改变年龄的类型为整型
但是书上是这样写的
ALTER TABLE student ALTER COLUMN Sage INT;
我用的是mysql这样才行,大概是版本吧。
ALTER TABLE student Modify Sage INT;
添加课程名称必须取唯一值的约束条件
ALTER TABLE course ADD UNIQUE(Cname);
4 删除表
DROP TABLE <表名> [RESTRICT|CASCADE]
默认是RESTRICT
2、索引的建立和删除
索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息。
最简单可以理解就是给某一列排排序,查找最小最大的时候就手到擒来,当然索引还有许多更厉害的结构。
1 建立索引
CREATE [UNIQUE] [CLUSTER] INDEX <索引名>
ON <表名>(<列名>[<次序>],[,<列名>[<次序>]]……);
为上面三个表建立索引
CREATE UNIQUE INDEX stusno ON student(Sno);
CREATE UNIQUE INDEX coucno ON course(Cno);
CREATE UNIQUE INDEX scno ON sc(Sno ASC,Cno DESC)
默认是升序
2 修改索引
只能改一个索引名字
ALTER INDEX <旧索引名字> RENAME TO <新索引名字>;
3 删除索引
索引建立起来以后就不用人为地去维护了,由系统自动维护,但是要是增删改查频繁的话,那么系统就会花费时间来维护索引,从而降低了查询效率,这是就可以删除不必要的索引
DROP INDEX <索引名>;
4 数据字典
数据字典是关系数据库管理系统内部的一组系统表,它记录了数据库中所有的定义信息,包括关系模式定义、视图定义、索引定义、完整性约束定义、各类用户对数据库的操作权限、统计信息等。关系数据库管理系统在执行SQL的数据定义语句时,实际上就是在更新数据字典表中的相应信息。在进行查询优化和查询处理时,数据字典中的信息是其重要依据。
数据字典是关于数据库中数据的描述,在需求分析阶段建立,是下一步进行概念设计的基础,并在数据库设计过程中不断修改、充实、完善。
3、数据查询
就是根据我各种需要查询数据,最常见的就是如下格式
SELECT [ALL|DISTINCT]<目标列表达式>[,<目标列表达式>]...
FROM<表名或者视图名> [,<表名或者视图名>...]|(<SELECT 语句>)[AS]<别名>
[WHERE<条件表达式>]
[GROUP BY<列名 1> [HAVING<条件表达式>]]
[ORDER BY<列名 2> [ASC|DESC]];
1 单表查询
就是只对一个表进行查询,这也能玩出花来
查询表中若干列
- 指定列
SELECT Sno,Sname FROM student
- 全部列
SELECT * FROM student
- 查询经过计算的值
SELECT Sname,2014-Sage FROM student
选择表中的若干组
- 消除取值重复的行
SELECT DISTINCT Sno FROM sc
- 查询满足条件的远组
就是我们喜闻乐见的WHERE
…
- ORDER BY 子句
可以排序的意思
SELECT Sno,Grade FROM sc WHERE Cno = 3 ORDER BY Grade DESC
SELECT *
FROM student
ORDER BY Sdept,Sage DESC
- 聚集函数
进一步方便用户吧,有一些方便的功能呢
默认是ALL
- GROUP BY子句
对查询出来的结果进行分组,但是要是用了聚集函数,则是以组来进行聚集
SELECT Cno, count(Sno)
FROM sc
GROUP BY Cno
还有一个HAVING函数
SELECT Sno,AVG(Grade)
FROM sc
GROUP BY Sno
HAVING AVG(Grade)>=86
WHERE是不能用聚集函数做条件表达式的,但是HAVING可以,HAVING是对分组后进行筛选,WHERE是对整个表或视图。
2 连接查询
这个就是对两个以上的表来查
- 等值与非等值连接查询
两个表的连接关系这样确定
SELECT student.*,sc.*
FROM sc,student
WHERE student.Sno = sc.Sno
当然也可以植入其他的WHERE条件用AND来连接
SELECT student.*,sc.*
FROM sc,student
WHERE student.Sno = sc.Sno AND
sc.Cno = 2 AND sc.Grade > 80
- 自身连接
自己与自己连,其实就是把这个表,看成两个一摸一样的表就好了,就酱
SELECT first.Cno,second.Cpno
from course first,course second
where first.Cpno = second.Cno
- 外连接
内连接:指连接结果仅包含符合连接条件的行,参与连接的两个表都应该符合连接条件。
外连接:连接结果不仅包含符合连接条件的行同时也包含自身不符合条件的行。包括左外连接、右外连接和全外连接。
左外连接:左边表数据行全部保留,右边表保留符合连接条件的行。
右外连接:右边表数据行全部保留,左边表保留符合连接条件的行。
全外连接:左外连接 union 右外连接。
select student.Sno,Sname,Ssex,Sage,Cno,Grade
from student left outer join sc on student.Sno = sc.Sno
左边为大,先将其数据全部列出来
- 多表连接
直接看例子
select student.Sno,Sname,Cname,Grade
from student,sc,course
where student.Sno = sc.Sno and sc.Cno = course.Cno
3 嵌套查询
大概意思就是可以在查询出来的结果上再进行查询
- 带有IN谓词的子查询
select Sno,Sname /*将选课的学生查询出来*/
from student
where Sno in (
select Sno /*将选课的学号查询出来*/
from sc
where Cno in (
select Cno /*将课程编号查询出来*/
from course
where Cname = '信息系统'
)
)
- 带有比较运算符的子查询
也是个相关查询的例子
select Sno,Cno
from sc x
where Grade >= (select AVG(Grade)
from sc y
where y.Sno = x.Sno
)
- 先把学生的学号拿出来
- 再计算该学生的的平均成绩
- 再执行条件,看哪个大于合适就显示出来
- 带有ANY(SOME)或ALL谓词的子查询
select Sname,Sage
from student
where Sage<ALL
(select Sage
from student
where Sdept='cs')
and Sdept<>'cs'
- 带有EXISTS谓词的子查询
就是返回真或假
select Sname
from student
where exists(select *
from sc
where sc.Sno = student.Sno)
4 集合查询
查询出来的多个元组进行操作,有并操作、交操作、还有差操作。MySQL只有并操作
select *
from student
where Sdept = 'cs'
union
select *
from student
where Sage<=19;
5 基于派生表的查询
从结果中得到结果
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;
4、数据更新
1 插入
直接插入数据
INSERT
INTO<表名>[(<属性列1>[,<属性列2>]...)]
VALUES(<常量1>[,<常量2>]...)
insert
into
student(sno, sname, ssex, sdept, sage)
VALUES (201215128,'程东','男','IS',18);
也能从子查询结果中插入
INSERT
INTO<表名>[(<属性列1>[,<属性列2>]...)]
子查询
insert
into dept_age(sdept, avg_age)
select Sdept,avg(Sage)
from student
group by Sdept
2 修改
UPDATE<表名>
SET<列名>=<表达式>[,<列名>=<表达式>]...
[WHERE<条件>];
3 删除
DELETE
FROM<表名>
[WHERE<条件>];
5、视图
它是从一个或者几个基本表导出的表,是个虚表。
在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表。
视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。我们可以向视图添加 SQL 函数、WHERE
以及 JOIN 语句,我们也可以提交数据,就像这些来自于某个单一的表。注释:数据库的设计和结构不会受到视图中的函数、where 或 join 语句的影响。
1 定义视图
- 建立视图
CREATE VIEW<视图名>[(<列名>[,<列名>]...)]
AS<子查询>
[WITH CHECK OPTION]
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM student
WHERE Sdept = 'IS'
操作完毕之后会在这里显示,显示view和table两个文件夹
在新建时可以添加别的一些语句
- 删除视图
DROP VIEW <视图名>[CASCADE];
2 查询视图
首先对视图进行有效性检查,检查查询中涉及的表、视图是否存在,如果存在,则从数据字典中取出视图的定义,把定义中的子查询和用户的查询结合起来,转换成等价的对基本表的查询,然后再执行修正了的查询。这一转换过程称为视图消解。
select Sno,Sage
FROM is_student
where Sage<20
3 更新视图
update is_student
set Sname='刘哈哈'
where sno=201215125;
is_student
student
按理说在视图添加,Sdept应该自动是IS,可我试了没有
6、数据控制
用户权限是由两个要素组成的:数据库对象和操作类型。定义一个用户的存取权限就是定义这个用户可以在哪些数据库对象上进行哪些类型的操作。在数据库系统中,定义存取权限称为授权
SQL中使用GRANT和REVOKE语句向用户授予或收回对数据的操作权限
1 GRANT
GRANT<权限>[,<权限>]...
ON<对象类型><对象名>[,<对象类型><对象名>]...
TO<用户>[,<用户>]...
[WITH GRANT OPTION];
有了WITH GRANT OPTION的用户,还可以把权限给别人
2 REVOKE
REVOKE<权限>[,<权限>]...
ON<对象类型><对象名>[,<对象类型><对象名>]...
FROM<用户>[,<用户>]...[CASCADE|RESTRICT];