《数据库概论》 第三章 关系数据库标准语言SQL

3.1 SQL概述

3.1.1 SQL的产生与发展

《数据库概论》 第三章 关系数据库标准语言SQL_第1张图片

3.1.2 SQL的特点

1.综合统一

①集数据定义(DDL)、数据操纵(DML)、数据控制(DCL)于一体

②独立完成全部活动 ③运行同时可随时修改 ④数据操作符统一

2.高度非过程化

SQL只要提“做什么”,无需了解存取路径

3.面向集合的操作方式

4.以同一种语法结构提供多种使用方式

①SQL是独立的语言

②SQL又是嵌入式语言(C、C++、Java)

5.语言简介

《数据库概论》 第三章 关系数据库标准语言SQL_第2张图片

3.1.3 SQL的基本概念

《数据库概论》 第三章 关系数据库标准语言SQL_第3张图片

SQL中一个关系对应一个基本表

一个(或多个)基本表对应一个存储文件

3.2 学生-课程数据库

学生-课程模式 S-T :    
	学生表:Student(Sno,Sname,Ssex,Sage,Sdept)
    课程表:Course(Cno,Cname,Cpno,Ccredit)
    学生选课表:SC(Sno,Cno,Grade)

3.3 数据定义

《数据库概论》 第三章 关系数据库标准语言SQL_第4张图片

  • 一个关系数据库管理系统可以建立多个数据库
  • 一个数据库可以建立多个模式
  • 一个模式可以包括多个表、视图、索引

3.3.1 模式的定义与删除

1.定义模式

为用户WANG定义一个学生-课程模式S-T
            CREATE SCHEMA “S-T” AUTHORIZATION WANG;
//AUTHORIZATION 指的是管理员

在这个空间中可以定义该模式包含的数据库对象,例如基本表、视图、索引等

在CREATE SCHEMA中可以接受CREATETABLE,CREATE VIEW和GRANT子句。

为用户ZHANG创建了一个模式TEST,并且在其中定义一个表TAB1

CREATE SCHEMA TEST AUTHORIZATION ZHANG 
CREATE TABLE TAB1   ( COL1 SMALLINT, 
                      COL2 INT,);

2.删除模式

DROP SCHEMA <模式名> 
CASCADE(级联):删除模式的同时把该模式中所有的数据库对象全部删除
RESTRICT(限制):如果该模式中定义了下属的数据库对象(如表、视图等),则拒绝该删除语句的执行。



DROP SCHEMA ZHANG CASCADE;
删除模式ZHANG,同时该模式中定义的表TAB1也被删除

3.3.2 基本表的定义、删除与修改

1.定义基本表

定义基本表
		CREATE TABLE <表名>
      (<列名> <数据类型>[ <列级完整性约束条件> ]
      [,<列名> <数据类型>[ <列级完整性约束条件>] ] 


如果完整性约束条件涉及到该表的多个属性列,则必须定义在表级上,否则既可以定义在列级也可以定义在表级。 
建立Student表
CREATE TABLE Student          
      (Sno   CHAR(9) PRIMARY KEY,  //列级完整性约束条件,Sno是主码*/                  
        Sname CHAR(20) UNIQUE,             // Sname取唯一值
        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)
//   Cpno是外码,被参照表是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.数据类型

《数据库概论》 第三章 关系数据库标准语言SQL_第5张图片

3.模式与表

①每一个基本表都属于一个模式

②一个模式包含多个表

4.修改基本表

ALTER TABLE <表名>
[ ADD[COLUMN] <新列名> <数据类型> [ 完整性约束 ] ]
[ ADD <表级完整性约束>]
[ DROP [ COLUMN ] <列名> [CASCADE| RESTRICT] ]
[ DROP CONSTRAINT<完整性约束名>[ RESTRICT | CASCADE ] ]
[ALTER COLUMN <列名><数据类型> ] ;


1.向Student表增加“入学时间”列,其数据类型为日期型
ALTER TABLE Student ADD S_entrance DATE;


2.将年龄的数据类型由字符型(假设原来的数据类型是字符型)改为整数

ALTER TABLE Student ALTER COLUMN Sage INT;



3.增加课程名称必须取唯一值的约束条件。

ALTER TABLE Course ADD UNIQUE(Cname); 

5.删除基本表

DROP TABLE <表名>[RESTRICT| CASCADE];

1.删除Student表
DROP TABLE  Student  CASCADE;

3.3.3 索引的建立与删除

建立索引目的:加快查询速度

  • B+树索引具有动态平衡的优点
  • HASH索引具有查找速度快的特点

谁创建索引:数据库管理员或表主人

谁维护索引:关系数据库管理系统自动完成

如何使用索引:关系数据库管理系统自动选择合适的索引作为存取路径,用户不必也不能显式地选择索引

1.建立索引

[例3.13] 为学生-课程数据库中的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);

2.修改索引

ALTER INDEX <旧索引名> RENAME TO <新索引名>

1.将SC表的SCno索引名改为SCSno
	ALTER INDEX SCno RENAME TO SCSno;

3.删除索引

DROP INDEX <索引名>;
删除索引时,系统会从数据字典中删去有关该索引的
描述。
1. 删除Student表的Stusname索引
	        DROP INDEX Stusname;

3.3.4 数据字典

数据字典是关系数据库管理系统内部的系统表,记录了所有定义信息:

关系模式、视图、索引、完整性约束、各类用户对数据库操作权限、统计信息

3.4 数据查询

3.4.1 单表查询

1.选择表中若干列

1.查询全体学生的学号与姓名。
SELECT Sno,Sname
FROM Student; 
 

2.查询全体学生的详细记录
SELECT  Sno,Sname,Ssex,Sage,Sdept 
FROM Student; 
或
SELECT  *
FROM Student; 


3.查全体学生的姓名及其出生年份。
SELECT Sname,2024-Sage 
FROM Student;


4.用列别名修改结果
SELECT Sname NAME,'Year of Birth:'  BIRTH,
       2024-Sage  BIRTHDAY,LOWER(Sdept)  DEPARTMENT
FROM Student;

2.选择表中若干元组

①比较大小

1.查询所有年龄在20岁以下的学生姓名及其年龄。
     SELECT Sname,Sage 
     FROM     Student    
     WHERE  Sage < 20;


2.查询考试成绩有不及格的学生的学号。
SELECT DISTINCT Sn
FROM  SC
WHERE Grade<60; 

②确定范围

谓词:   BETWEEN …  AND  …
        NOT BETWEEN  …  AND  …

1.查询年龄在20~23岁(包括20岁和23岁)之间的学生的姓名、系别和年龄
SELECT Sname, Sdept, Sage
FROM     Student
WHERE   Sage BETWEEN 20 AND 23; 

③确定集合

谓词:IN <值表>,  NOT IN <值表>  
        
1.查询计算机科学系(CS)、数学系(MA)和信息系(IS)学生的姓名和性别。
	SELECT Sname, Ssex
	FROM  Student
	WHERE Sdept IN ('CS','MA’,'IS' );

④字符匹配

谓词: [NOT] LIKE  ‘<匹配串>’  [ESCAPE ‘ <换码字符>’]

<匹配串>可以是一个完整的字符串,也可以含有通配符%和 _

1.查询所有姓刘学生的姓名、学号和性别。
       SELECT Sname, Sno, Ssex
      FROM Student
      WHERE  Sname LIKE '刘%';


2.查询姓"欧阳"且全名为三个汉字的学生的姓名。
       SELECT Sname
      FROM   Student
      WHERE  Sname LIKE '欧阳__';

⑤涉及空值查询

谓词: IS NULL 或 IS NOT NULL
 “IS” 不能用 “=” 代替
	[例3.36]  某些学生选修课程后没有参加考试,所以有选课记录,但没 有考试成绩。查询缺少成绩的学生的学号和相应的课程号。
	  SELECT Sno,Cno
      FROM    SC
      WHERE  Grade IS NULL

⑥多重条件查询

逻辑运算符:AND和 OR来连接多个查询条件
 AND的优先级高于OR
 可以用括号改变优先级

1.查询计算机系年龄在20岁以下的学生姓名。
      SELECT Sname
       FROM  Student
       WHERE Sdept= 'CS' AND Sage<20;

3.ORDER BY语句

1.查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列。
        SELECT Sno, Grade
        FROM    SC
        WHERE  Cno= ' 3 '
        ORDER BY Grade DESC;

ASC为升序;DESC为降序;

4.聚集函数

聚集函数:
统计元组个数
     COUNT(*)
统计一列中值的个数
     COUNT([DISTINCT|ALL] <列名>)
计算一列值的总和(此列必须为数值型)
SUM([DISTINCT|ALL] <列名>)	
计算一列值的平均值(此列必须为数值型)
AVG([DISTINCT|ALL] <列名>)
求一列中的最大值和最小值
 	 MAX([DISTINCT|ALL] <列名>)
	 MIN([DISTINCT|ALL] <列名>)

5.GROUP BY语句

细化聚集函数的作用对象:

①如果未对查询结果分组,聚集函数将作用于整个查询结果

②对查询结果分组后,聚集函数将分别作用于每个组

③按指定的一列或多列值分组,值相等的为一组

查询选修了3门以上课程的学生学号。
SELECT Sno
FROM  SC
GROUP BY Sno
     HAVING  COUNT(*) >3;       

3.4.2 连接查询

连接查询:同时涉及两个以上的表的查询

连接条件或连接谓词:用来连接两个表的条件

1.等值与非等值连接查询

1.查询每个学生及其选修课程的情况
SELECT  Student.*, SC.*
FROM     Student, SC
WHERE  Student.Sno = SC.Sno;

2.查询选修2号课程且成绩在90分以上的所有学生的学号和姓名。
SELECT Student.Sno, Sname
FROM     Student, SC
WHERE  Student.Sno=SC.Sno  AND    		             SC.Cno=' 2 ' AND SC.Grade>90;

2.自身连接

自身连接:一个表与其自己进行连接

需要给表起别名以示区别

1.查询每一门课的间接先修课(即先修课的先修课)
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 OUT JOIN SC ON (Student.Sno=SC.Sno); 

4.多表连接

多表连接:两个以上的表进行连接

查询每个学生的学号、姓名、选修的课程名及成绩
SELECT Student.Sno, Sname, Cname, Grade
FROM    Student, SC, Course    /*多表连接*/
WHERE Student.Sno = SC.Sno 
AND SC.Cno = Course.Cno;

3.4.3 嵌套查询

嵌套查询:

①一个SELECT-FROM-WHERE语句作为一个查询块

②将另一个查询块嵌套在WHERE语句中

③子查询不能使用ORDER BY语句

不相关子查询:子查询查询条件不依赖于父查询

相关子查询:子查询查询条件依赖于父查询

1.带有IN谓词的子查询

1.查询与“刘晨”在同一个系学习的学生。
此查询要求可以分步来完成
① 确定“刘晨”所在系名             
         SELECT  Sdept  
         FROM     Student                            
         WHERE  Sname= ' 刘晨 ';
	      结果为: CS
② 查找所有在CS系学习的学生。    
        SELECT   Sno, Sname, Sdept     
        FROM      Student                 
        WHERE   Sdept= ' CS '; 

最终:
SELECT Sno, Sname, Sdept FROM Student
WHERE Sdept  IN
      (SELECT Sdept
       FROM Student
       WHERE Sname= ' 刘晨 ');


 用自身连接完成查询要求
SELECT  S1.Sno, S1.Sname,S1.Sdept
FROM     Student S1,Student S2
WHERE  S1.Sdept = S2.Sdept  AND S2.Sname = '刘晨';

2.带有比较运算符的子查询

1.找出每个学生超过他选修课程平均成绩的课程号。
SELECT Sno, Cno
FROM    SC  x
WHERE Grade >=(SELECT AVG(Grade) FROM  SC y WHERE y.Sno=x.Sno);

3.带有ANY(SOME)或ALL谓词的子查询

1.查询非计算机科学系中比计算机科学系所有学生年龄都小的学生姓名及年龄。
SELECT Sname,Sage
FROM Student
WHERE Sage < ALL
(SELECT Sage
FROM Student
WHERE Sdept= ' CS ')

4.带有EXISTS谓词的子查询

带有EXISTS子查询不返回任何数据,只产生逻辑“true”或“false”

由EXISTS引出的子查询,其目标列表达式通常都用",因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义。

1.查询所有选修了1号课程的学生姓名。
SELECT Sname
FROM Student
WHERE EXISTS
(SELECT *
FROM SC
WHERE Sno=Student.Sno AND Cno= ' 1 ');

所有带IN谓词、比较运算符、ANY和ALL谓词子查询都能用带EXISTS谓词子查询替代

1.查询选修了全部课程的学生姓名。
SELECT Sname
FROM Student
WHERE NOT EXISTS
(SELECT *
FROM Course
WHERE NOT EXISTS
(SELECT *
FROM SC
WHERE Sno= Student.Sno
AND Cno= Course.Cno
)
);

3.4.4 集合查询

种类:

并操作UNION

交操作:INTERSECT

差操作:EXCEPT

参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同

1.查询计算机科学系的学生及年龄不大于19岁的学生。
        SELECT *
        FROM Student
        WHERE Sdept= 'CS'
        UNION
        SELECT *
        FROM Student
        WHERE Sage<=19;

UNION:将多个查询结果合并起来时,系统自动去掉重复元组
UNION ALL:将多个查询结果合并起来时,保留重复元组 


2.查询既选修了课程1又选修了课程2的学生。
	SELECT Sno
    FROM SC
    WHERE Cno=' 1 ' 
    INTERSECT
    SELECT Sno
    FROM SC
    WHERE Cno='2 ';

3.查询计算机科学系的学生与年龄不大于19岁的学生的差集。
    SELECT *
    FROM Student
    WHERE Sdept='CS'
    EXCEPT
    SELECT  *
    FROM Student
    WHERE Sage <=19;

3.4.5 基于派生表的查询

子查询可以放于FROM子句中,成为主查询的查询对象

1.找出每个学生超过他自己选修课程平均成绩的课程号
     
    SELECT Sno, Cno
    FROM SC, (SELECTSno, 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

3.4.6 Select语句的一般形式

 SELECT [ALL|DISTINCT]  
   <目标列表达式> [别名] [ ,<目标列表达式> [别名]] …
 FROM     <表名或视图名> [别名] 
                [ ,<表名或视图名> [别名]] …
                |()[AS]<别名>
 [WHERE <条件表达式>]
 [GROUP BY <列名1>[HAVING<条件表达式>]]
 [ORDER BY <列名2> [ASC|DESC]];

3.5 数据更新

3.5.1 插入数据

1.插入元组

	INSERT
	INTO <表名> [(<属性列1>[,<属性列2 >…)]
	VALUES (<常量1> [,<常量2>]… );
将一个新学生元组(学号:201215128;姓名:陈冬;性别:男;所在系:IS;年龄:18岁)插入到Student表中。

    INSERT
    INTO  Student (Sno,Sname,Ssex,Sdept,Sage)
    VALUES ('201215128','陈冬','男','IS',18);

2.插入子查询结果

    INSERT 
     INTO <表名>  [(<属性列1> [,<属性列2>…  )]
 	子查询;
对每一个系,求学生的平均年龄,并把结果存入数据库
第一步:建表
      CREATE  TABLE  Dept_age
          ( Sdept     CHAR(15)                     /*系名*/
            Avg_age SMALLINT);          	/*学生平均年龄*/
第二步:插入数据
       INSERT
       INTO  Dept_age(Sdept,Avg_age)
              SELECT  Sdept,AVG(Sage)
              FROM     Student
              GROUP BY Sdept;

3.5.2 修改数据

1.修改某一个元组的值

UPDATE  Student
SET Sage=22
WHERE  Sno=' 201215121 '; 

2.修改多个元组的值

UPDATE Student
SET Sage= Sage+1;

3.带子查询的修改语句

将计算机科学系全体学生的成绩置零。
UPDATE SC
SET     Grade=0
WHERE Sno  IN
(SELETE Sno
FROM     Student
WHERE  Sdept= 'CS' );

修改过程中,会检查是否破坏定义的完整性规则:

①实体完整性

②主码不允许修改

③用户定义完整性:NOT  NULL约束、UNIQUE约束、值域约束

3.5.3 删除数据

DELETE
FROM     <表名>
[WHERE <条件>];

1.删除某一个元组的值

删除学号为201215128的学生记录。
DELETE
FROM Student
WHERE Sno= 201215128 ';

2.删除多个元组的值

删除所有的学生选课记录。
DELETE
FROM SC;

3.带子查询的删除语句

删除计算机科学系所有学生的选课记录。
DELETE
WHERE  Sno  IN
(SELETE  Sno
FROM   Student
WHERE  Sdept= 'CS') ;

3.6 空值的处理

空值情况:

①不知道属性具体值

②属性不应该有值

③由于某种原因不便于填写

1.空值的产生

向SC表中插入一个元组,学生号是”201215126”,课程号是”1”,成绩为空。
 INSERT INTO SC(Sno,Cno,Grade)
 VALUES('201215126 ','1',NULL);   /*该学生还没有考试成绩,取空值*/
或
 INSERT INTO SC(Sno,Cno)
 VALUES(' 201215126 ','1');             /*没有赋值的属性,其值为空值*/

2.空值的判断

判断一个属性是否为空值,用IS NULL或IS NOT NULL表示

3.空值的约束条件

①NOT NULL约束条件不能取空值

②加了UNIQUE限制属性不能取空值

③码属性不能取空值

4.空值的算术运算、比较运算和逻辑运算

空值与另一个值(包括空值)比较结果为UNKNOWN

选出选修1号课程的不及格的学生以及缺考的学生。
SELECT Sno
FROM SC
WHERE Grade < 60 AND Cno='1'
UNION
SELECT Sno
FROM SC
WHERE Grade IS NULL AND Cno='1'
或者
SELECT Sno
FROM SC
WHERE Cno='1' AND (Grade<60 OR Grade IS NULL);

3.7 视图

①虚表,从一个或几个基本表导出来的表

②只存放视图定义,不存放数据

③基本表数据变化,视图查询的数据也随之改变

3.7.1 定义视图

1.建立视图

语句格式
       CREATE  VIEW <视图名>  [(<列名>  [,<列名>]…)]
       AS  <子查询>
       [WITH  CHECK  OPTION];


关系数据库管理系统执行CREATE VIEW语句时只是把视图定义存入数据字典,并不执行其中的SELECT语句。


在对视图查询时,按视图的定义从基本表中将数据查出。
建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系的学生 。
        CREATE VIEW IS_Student
        AS 
        SELECT Sno,Sname,Sage
        FROM  Student
        WHERE  Sdept= 'IS'
        WITH CHECK OPTION;

定义IS_Student视图时加上了WITH CHECK OPTION子句,对该视图进行插入、修改和删除操作时,RDBMS会自动加上Sdept='IS'的条件。


若一个视图是从单个基本表导出的,并且只是去掉了基本表的某些行和某些列,但保留了主码,我们称这类视图为行列子集视图。

2.删除视图

DROP  VIEW  <视图名>[CASCADE];


删除基表时,由该基表导出的所有视图定义都必须显式地使用DROP VIEW语句删除 
删除视图BT_S和IS_S1
		DROP VIEW BT_S;	/*成功执行*/
		DROP VIEW IS_S1;	/*拒绝执行*/
	      
        要删除IS_S1,需使用级联删除:
        DROP VIEW IS_S1 CASCADE;            

3.7.2 查询视图

用户角度:查询视图与查询基本表相同

关系数据库管理系统实现视图查询方法:

①进行有效性检查

②转换成等价的对基本表的查询

③执行修正后的查询

3.7.3 更新视图

向信息系学生视图IS_S中插入一个新的学生记录,其中学号为”201215129”,姓名为”赵新”,年龄为20岁
INSERT
INTO IS_Student
VALUES(‘201215129’,’赵新’,20);
转换为对基本表的更新:
INSERT
INTO   Student(Sno,Sname,Sage,Sdept)
VALUES(‘200215129 ','赵新',20,'IS' );

更新的限制:

  1. 若视图是由两个以上基本表导出的,则此视图不允许更新
  2. 若视图的字段来自字段表达式或常数,则不允许对此视图执行INSERT和UPDATE操作,但允许执行DELETE操作
  3. 若视图的字段来自集函数,则此视图不允许更新。
  4. 若视图定义中含有GROUP BY子句,则此视图不允许更新
  5. 若视图定义中含有DISTINCT短语,则此视图不允许更新。
  6. 若视图定义中有嵌套查询,并且内层查询的FROM子句中涉及的表也是导出该视图的基本表,则此视图不允许更新

3.7.4 视图的作用

①简化用户操作

②使用户以多种角度看待同一数据

③对重构数据库提供了一定程度的逻辑独立性

④能够对机密数据提供安全保护

⑤可以更清晰的表达查询

你可能感兴趣的:(数据库,数据库)