1、模式的定义与删除
1.1 定义模式
在CREATE SCHEMA中可以接受CREATE TABLE,CREATE VIEW和GRANT子句,语句如下:
CREATE SCHEMA <模式名> AUTHORIZATION <用户名>[<表定义子句>|<视图定义子句>|<授权定义子句>]
例子:为用户ZHANG创建了一个模式TEST,并且在其中定义一个表TAB1
CREATE SCHEMA TEST AUTHORIZATION ZHANG
CREATE TABLE TAB1 (
COL1 SMALLINT,
COL2 INT,
COL3 CHAR(20),
COL4 NUMERIC(10,3),
COL5 DECIMAL(5,2)
);
1.2 删除模式
语句格式:
DROP SCHEMA <模式名> <CASCADE|RESTRICT>
- CASCADE(级联)
删除模式的同时把该模式中所有的数据库对象全部删除 - RESTRICT(限制)
如果该模式中定义了下属的数据库对象(如表、视图等),则拒绝该删除语句的执行;
仅当该模式中没有任何下属的对象时才能执行。
例子: 删除模式ZHANG, 同时该模式中定义的表TAB1也被删除
DROP SCHEMA ZHANG CASCADE;
2、基本表的定义、删除与修改
数据类型
2.1 定义表
语句格式:
CREATE TABLE <表名>
(<列名> <数据类型>[ <列级完整性约束条件> ]
[,<列名> <数据类型>[ <列级完整性约束条件>] ]
…
[,<表级完整性约束条件> ] );
例子:
//建立一个“课程”表Course
CREATE TABLE Course
( Cno CHAR(4) PRIMARY KEY, //主键
Cname CHAR(40),
Cpno CHAR(4),
Ccredit SMALLINT,
FOREIGN KEY (Cpno) REFERENCES Course(Cno) //外键,Course(Cno)为被参照表(被参照列)
);
//建立一个学生选课表SC
CREATE TABLE SC
( Sno CHAR(9),
Cno CHAR(4),
Grade SMALLINT,
PRIMARY KEY (Sno,Cno), /* 主码由两个属性构成,必须作为表级完整性进行定义*/
FOREIGN KEY (Sno) REFERENCES Student(Sno), /* 表级完整性约束条件,Sno是外码,被参照表是Student */
FOREIGN KEY (Cno)REFERENCES Course(Cno) /* 表级完整性约束条件, Cno是外码,被参照表是Course*/
);
2.2 定义表的所属模式
方法一:在表名中明显地给出模式名
Create table"S-T".Student(......); /*模式名为 S-T*/
Create table "S-T".Cource(......);
Create table "S-T".SC(......);
方法二:在创建模式语句中同时创建表
CREATE SCHEMA TEST AUTHORIZATION ZHANG
CREATE TABLE TAB1 (
COL1 SMALLINT,
COL2 INT,
COL3 CHAR(20),
COL4 NUMERIC(10,3),
COL5 DECIMAL(5,2)
);
方法三:设置所属的模式
- 创建基本表(其他数据库对象也一样)时,若没有指定模式,系统根据搜索路径来确定该对象所属的模式
- 关系数据库管理系统会使用模式列表中第一个存在的模式作为数据库对象的模式名
- 若搜索路径中的模式名都不存在,系统将给出错误
显示当前的搜索路径: SHOW search_path;
搜索路径的当前默认值是:$user, PUBLIC
设置搜索路径,然后定义基本表 :
SET search_path TO "S-T",PUBLIC; //设置搜索路径
Create table Student(......); //定义基本表
结果建立了S-T.Student基本表
2.3 修改表
语句格式:
ALTER TABLE <表名>
[ ADD[COLUMN] <新列名> <数据类型> [ 完整性约束 ] ]
[ ADD <表级完整性约束>]
[ DROP [ COLUMN ] <列名> [CASCADE| RESTRICT] ]
[ DROP CONSTRAINT<完整性约束名>[ RESTRICT | CASCADE ] ]
[ALTER COLUMN <列名><数据类型> ] ;
- <表名>是要修改的基本表
- ADD子句用于增加新列、新的列级完整性约束条件和新的表级完整性约束条件
- DROP COLUMN子句用于删除表中的列
如果指定了CASCADE短语,则自动删除引用了该列的其他对象
如果指定了RESTRICT短语,则如果该列被其他对象引用,关系数据库管理系统将拒绝删除该列 - DROP CONSTRAINT子句用于删除指定的完整性约束条件
- ALTER COLUMN子句用于修改原有的列定义,包括修改列名和数据类型
例子:
//添加属性
ALTER TABLE Student ADD S_entrance DATE;
//修改属性Sage的数据类型
ALTER TABLE Student modify COLUMN Sage INT;
//给Cname属性添加约束条件UNIQUE
ALTER TABLE Course ADD UNIQUE(Cname);
2.4 删除表
语句格式:
DROP TABLE <表名>[RESTRICT| CASCADE];
- RESTRICT:删除表是有限制的
欲删除的基本表不能被其他表的约束所引用;
如果存在依赖该表的对象,则此表不能被删除 - CASCADE:删除该表没有限制
在删除基本表的同时,相关的依赖对象(表定义、数据、索引、视图、触发器等)一起删除
例子:删除Student表
DROP TABLE Student CASCADE; //基本表定义被删除,数据被删除,表上建立的索引、视图、触发器等一般也将被删除
3、索引的建立与删除
3.1 创建索引
语句格式:
CREATE [UNIQUE] [CLUSTER] INDEX <索引名>
ON <表名>(<列名>[<次序>][,<列名>[<次序>] ]…);
- <表名>:要建索引的基本表的名字
- 索引:可以建立在该表的一列或多列上,各列名之间用逗号分隔
- <次序>:指定索引值的排列次序,升序:ASC,降序:DESC。缺省值:ASC
- UNIQUE:此索引的每一个索引值只对应唯一的数据记录
- CLUSTER:表示要建立的索引是聚簇索引
例子:为学生-课程数据库中的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);
3.2 修改索引
语句格式:
ALTER INDEX <旧索引名> RENAME TO <新索引名>
例子:将SC表的SCno索引名改为SCSno
ALTER INDEX SCno RENAME TO SCSno;
3.3 删除索引
删除索引时,系统会从数据字典中删去有关该索引的描述
语句格式:
DROP INDEX <索引名>;
例子:删除Student表的Stusname索引
DROP INDEX Stusname;
4、视图的创建与删除
4.1 创建视图
语句格式
CREATE VIEW <视图名> [(<列名> [,<列名>]…)]
AS <子查询>
[WITH CHECK OPTION];
1、子查询可以是任意的SELECT语句,是否可以含有ORDER BY子句和DISTINCT短语,则决定具体系统的实现
2、WITH CHECK OPTION:对视图进行UPDATE,INSERT和DELETE操作时要保证更新、插入或删除的行满足视图定义中的谓词条件(即子查询中的条件表达式)
注:修改基表的结构后,可能导致表与视图的映象关系被破坏,从而导致该视图不能正确工作
例1:建立信息系学生的视图
CREATE VIEW IS_Student
AS SELECT Sno,Sname,Sage FROM Student WHERE Sdept= 'IS';
例2:建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系的学生
CREATE VIEW IS_Student
AS SELECT Sno,Sname,Sage FROM Student WHERE Sdept= 'IS'
WITH CHECK OPTION;
4.1.1 基于多个基表的视图
例3:建立信息系选修了1号课程的学生的视图(包括学号、姓名、成绩)
CREATE VIEW IS_S1(Sno,Sname,Grade)
AS SELECT Student.Sno,Sname,Grade FROM Student,SC
WHERE Sdept= 'IS' AND Student.Sno=SC.Sno AND SC.Cno= '1';
4.1.2 基于视图的视图
例4:建立信息系选修了1号课程且成绩在90分以上的学生的视图
// IS_S2 基于视图IS_s1:FROM IS_S1
CREATE VIEW IS_S2
AS SELECT Sno,Sname,Grade FROM IS_S1 WHERE Grade>=90;
4.1.3 带表达式的视图
例5:定义一个反映学生出生年份的视图
// 表达式:2014-Sage
CREATE VIEW BT_S(Sno,Sname,Sbirth)
AS SELECT Sno,Sname,2014-Sage FROM Student;
4.1.4分组视图
例6:将学生的学号及平均成绩定义为一个视图
// 分组:GROUP BY
CREAT VIEW S_G(Sno,Gavg)
AS SELECT Sno,AVG(Grade) FROM SC GROUP BY Sno;
4.2 删除视图
语句的格式:
DROP VIEW <视图名>[CASCADE];
- 该语句从数据字典中删除指定的视图定义
- 如果该视图上还导出了其他视图,使用CASCADE级联删除语句,把该视图和由它导出的所有视图一起删除
- 删除基表时,由该基表导出的所有视图定义都必须显式地使用DROP VIEW语句删除
4.3 查询视图
查询视图与查询基本表相同
例子:在信息系学生的视图中找出年龄小于20岁的学生
SELECT Sno,Sage FROM IS_Student WHERE Sage<20;
4.4 更新视图
更新视图和更新基本表相同
注:一些视图是不可更新的——当对视图的更新无法转换成对基本表SC的更新时,如修改平均成绩视图中某个学生的平均成绩不可实现
例:
// 插入
INSERT INTO IS_Student VALUES(‘201215129’,’赵新’,20);
// 修改
UPDATE IS_Student SET Sname= '刘辰' WHERE Sno= ' 201215122 ';
// 删除
DELETE FROM IS_Student WHERE Sno= ' 201215129 ';
5、查询操作
5.1 单表查询
语句格式:
SELECT [ALL|DISTINCT] <目标列表达式>[,<目标列表达式>] …
FROM <表名或视图名>[,<表名或视图名> ]…|(SELECT 语句)
[AS]<别名>
[ WHERE <条件表达式> ]
[ GROUP BY <列名1> [ HAVING <条件表达式> ] ]
[ ORDER BY <列名2> [ ASC|DESC ] ];
- SELECT子句:指定要显示的属性列
- <目标列表达式>:指定查询的表中的属性列,或者表达式
- FROM子句:指定查询对象(基本表或视图)
- WHERE子句:指定查询条件
- GROUP BY子句:对查询结果按指定列的值分组,该属性列值相等的元组为一个组。通常会在每组中作用聚集函数。
- HAVING短语:只有满足指定条件的组才予以输出
- ORDER BY子句:对查询结果表按指定列值的升序或降序排序
1、查询指定列
2、查询全部列
3、查询经过计算的值:详情链接
4、使用列别名改变查询结果的列标题
SELECT Sname NAME,'Year of Birth:' BIRTH,2014-Sage BIRTHDAY,LOWER(Sdept) DEPARTMENT
FROM Student;
输出结果:
NAME | BIRTH | BIRTHDAY | DEPARTMENT |
---|---|---|---|
李勇 | Year of Birth: | 1994 | cs |
刘晨 | Year of Birth: | 1995 | cs |
王敏 | Year of Birth: | 1996 | ma |
张立 | Year of Birth: | 1995 | is |
5.2 连接查询(后续补充)
查询涉及两个及以上表
5.3 嵌套查询
一个SELECT-FROM-WHERE语句称为一个查询块,将一个查询块嵌套在另一个查询块的WHERE子句HAVING短语的条件中的查询称为嵌套查询
子查询的限制:不能使用ORDER BY子句
1子查询
(1)相关子查询:在外层查询的每一个循环中处理内查询。子查询的查询条件依赖于父查询
(2)不相关子查询:由里向外 逐层处理。子查询的查询条件不依赖于父查询
5.3.1 带有IN谓词的子查询
例题1:查询与“刘晨”在同一个系学习的学生
(1)嵌套查询(不相关子查询)
SELECT Sno, Sname, Sdept FROM Student
WHERE Sdept IN
(SELECT Sdept
FROM Student
WHERE Sname= ' 刘晨 ');
(2)自身连接
SELECT S1.Sno, S1.Sname,S1.Sdept
FROM Student S1,Student S2
WHERE S1.Sdept = S2.Sdept AND S2.Sname = '刘晨';
例题2:查询选修了课程名为“信息系统”的学生学号和姓名
(1)嵌套查询
SELECT Sno,Sname ③ 最后在Student关系中取出Sno和Sname
FROM Student
WHERE Sno IN
( SELECT Sno ② 然后在SC关系中找出选修了3号课程的学生学号
FROM SC
WHERE Cno IN
( SELECT Cno ① 首先在Course关系中找出“信息系统”的课程号,为3号
FROM Course
WHERE Cname= '信息系统'
)
);
(2)连接查询
SELECT Sno,Sname FROM Student,SC,Course
WHERE Student.Sno = SC.Sno AND SC.Cno = Course.Cno AND Course.Cname='信息系统';
5.3.2 带有比较运算符的子查询
例题:找出每个学生超过他选修课程平均成绩的课程号
嵌套查询(相关子查询)
SELECT Sno, Cno FROM SC x
WHERE Grade >=(SELECT AVG(Grade) FROM SC y WHERE y.Sno=x.Sno);
过程:
- 外层取出一个元组x,将x的sno传给内层
- 内层查询到结果,用该结果代替内层查询,进行外层查询,得出元组x对应的结果
- 重复,直至完成外层所有元组