1,SQL概述

1.1,SQL的组成

结构化查询语言简称SQL(Structured Query Language)是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;同时也是数据库脚本文件的扩展名

SQL的功能包括:数据查询、数据操纵、数据定义和数据控制4个部分:

  • 数据查询语句:数据库最基本的操作,通过select语句可以得到所需的信息。
  • 数据操纵语言(DML,Data Manipulation Language):主要包括插入数据、修改数据以及删除数据。
  • 数据定义语言(DDL,Data Definition Language):实现数据定义功能,可对数据库用户、基本表、视图、索引进行定义与撤销。
  • 数据控制语句(DCL,Data Control Language):用于对数据库进行统一的控制管理,保证数据在多用户共享的情况下能够安全。

SQL的特点:

  • 综合统一:集数据定义语言DDL、数据操纵语言DML、数据控制语言DCL的功能于一体,语言风格统一,可以独立完成数据库生命周期中的全部活动。定义关系模式,建立数据库,对数据进行查询和更新,数据库重构和维护,数据库完整性安全性控制等。可以在不影响数据库运行的情况下对数据库进行模式的修改。实体及实体间的联系都用关系表示,数据结构的单一性带来操作符的统一,简化了操作。
  • 高度非过程化:用户只需提出“做什么”,无须告诉“怎么做”,不必了解存取路径,路径的选择及SQL的操作过程由系统自动完成,减轻了用户的负担,有利于提高数据独立性
  • 面向集合的操作方式:集合SQL采用集合操作方式,操作对象和操作结果都是关系 --- 元组,可以一次插入、删除、更新整个集合的元组。
  • 两种使用方式,统一的语法结构:SQL既是自含式语言(用户使用),又是嵌入式语言(程序员使用), 不同的使用方式, 但语法结构基本是一致的。
  • 语言简洁,语法简单,接近英语口语,易学易用:SQL完成核心的功能只用了9个命令动词。

1.2,SQL的基本概念

SQL语言支持关系数据库三级模式结构。即SQL数据库的体系结构基本上也是三级结构,但术语与传统的关系模型术语不同

基本表:基本表是独立、存在的表,SQL中一个关系就对应一个基本表(基表);一个基表上可以带多个索引,索引存放在存储文件里;

视图:视图是一个或多个基表导出的表,数据库中只存放视图定义以及与其关联的基本表名等信息,而不存放视图对应的数据;数据仍存放在导出视图的基本表中,因此视图又称为虚拟表。

存储文件:由多个基本表、视图、相关索引和存储过程等数据库对象组成;存储文件的逻辑结构对应数据库的内模式。

1.3,SQL数据库体系结构

SQL用户可以用SQL语句对基本表和视图进行查询等操作,在用户看来,两者是一样的,都是表。

一个基本表只能放一个存储文件中;一个存储文件可以放一个或多个基本表。每个存储文件都与外存储器上的一个物理文件对应。一个表可以带若干索引,索引也放在存储文件中

视图是从一个或几个基本表中导出的表,数据库中只存放视图的定义。

2,数据定义

操作对象操作方式
创建删除修改
数据库(模式)create databasedrop database
表(关系)create tabledrop tablealter table
视图create viewdrop view
索引create indexdrop indexalter index

2.1,数据库(模式)的定义与删除

create database YSY;

定义模式实际上定义了一个命名空间。

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

drop database YSY;

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

基本单位:MySQL 数据类型 | 菜鸟教程

create table YSY(A int primary key,
                 B char(20) not null,
                 C int not null unique,
                 foreign key(C) references YSY2(C));

模(数据库)式与表:每一个基本表都属于某一个模式;一个模式包含多个基本表

alert table YSY add schoolName char(20);
drop table YSY;

2.3,数据字典

软件工程:可行性研究_燕双嘤的博客-CSDN博客_软件可行性研究

3,数据查询

3.1,数据查询

单列查询select name from student;
全部列查询select * from student;
部分列查询select name,number from student;
设置别名select name as studentName from sutdent;
计算列值select 2020-age from student;
消除重复项select distinct sex from student;
限制查询行数select top 10 * from student;
查询满足条件比较运算符

select number from student where name='燕双嘤';

select name from student where age<20;

确定范围

select name from student where age between 20 and 23;

select name from student where age not between 20 and 23;

确定集合

select number from student where name in('燕双嘤','滑小稽');

select number from student where name not in('燕双嘤','滑小稽');

模糊查询

% (百分号)  代表任意长度的字符串

a%b表示以a开头,以b结尾的任意长度的字符串

select * from student where name like '燕%嘤'

select * from student where name not like '燕%嘤'

_ (下横线)  代表任意单个字符

a_b表示以a开头,以b结尾的长度为3的任意字符串

select * from student where name like '燕_嘤'

select * from student where name not like '燕_嘤'

涉空查询select * from student where grade is null;
多重查询select * from student where name='燕双嘤' and age='21';
排序正序select * from student order by grade asc;正序默认,可省略;
倒序select * from student oder by grade desc;

3.2,聚集函数

SELECT语句中可以使用统计函数进行统计,并返回统计结果。聚合函数用于处理单个列中所选的全部值,并生成一个结果值。常用的聚合函数(也称统计函数)包括COUNT()AVG()SUM()MAX()、和MIN()

count():统计元组数目。

select count(*) from student;

sum():统计元组的某项和。

select sum(grade) from student;

max(),min():统计最大值,最小值。

select max(age)/min(age) from student;

3.3,分组查询

GROUP BY子句用于对表或视图中的数据按字段分组,还可以利用HAVING短语按照一定的条件对分组后的数据进行筛选。

★格式:GROUP BY [ALL] 分组表达式 [HAVING 查询条件]

  • 当使用HAVING短语指定筛选条件时,HAVING短语必须与GROUP BY配合使用。
  • 如果未对查询结果分组,聚集函数将作用于整个查询结果。
  • 对查询结果分组后,聚集函数将分别作用于每个组。
  • 按指定的一列或多列值分组,值相等的为一组。
select count(name) from student group by sex;//查询男女人数
select number from schoolClass group by number having count(*)>3;//查询有三个课程的学生

WHERE 子句和HAVING 短语的区别,在于作用的对象不同, WHERE作用于基本表或视图, 从中选择满足条件的元组。HAVING作用于组,从中选择满足条件的组。 HAVING一定要结合GROUP使用。

3.4,连接查询

连接类型:等值连接、自然连接、非等值连接。自身连接(一个表自己和自己连接)。内连接(即自然连接)。外连接(左、右、全)。⑤复合条件连接

等值连接:连接条件是在WHERE子句中给出的,只有满足连接条件的行才会出现在查询结果中

select student.*,schoolClass.* from student,schoolClass where student.number=schoolClass.number;

自然连接:公共属性上的等值连接,结果中把目标列中重复的属性列去掉

select student.number,name,sex,className,grade from student,schoolGrade where student.number=schoolGrade.number;

非等值连接:等值连接基础上破坏满足条件。

select student.number,name from student,schoolClass where student.number=schoolClass.number and schoolClass.number='2' and schoolClass.grade > 90;

自身连接:一个表与其自己连接。

select first.name,second.number from student first,student second where first.number=second.number;

外连接:普通连接操作只输出满足连接条件的元组,而外连接操作以指定表为连接主体,将主体表中不满足连接条件的元组一并输出。连接分为:左外连接(列出左边关系中所有的元组 )和 右外连接(列出右边关系中所有的元组

注意:*表示为所在边的表(例中是SC表)增加一个“万能”的行,这个行全部由空值组成,它可以和另一边的表(例中是Student表)中所有不满足连接条件的元组(称失配的元组)进行连接

左外连接,左边表放*万能行;右外连接,右边表放*万能行

select student.number,name,sex,age,className,grade from student,schoolClass where student.number=schoolClass.number(*);//左连接
select student.number,name,sex,age,className,grade from student,schoolClass where student.number(*)=schoolClass.number;//右连接

T-SQL扩展了连接的形式,引入了JOIN...ON关键字连接形式,从而使表的连接运算得到了增强。

JOIN提供了多种类型的连接方法:内连接、外连接和交叉连接。

内连接/普通连接/自然连接SELECT student.sno,sname,sdept,cno,grade  FROM student JOIN sc ON student.sno=sc.sno
外连接-左外连接SELECT student.sno,cno,sname,grade FROM student LEFT JOIN sc ON sc.sno=student.sno
外连接-右外连接SELECT student.sno,cno,sname,grade FROM student RIGHT JOIN sc ON sc.sno=student.sno
交叉连接

SELECT student.*,sc.* FROM student CROSS JOIN sc

即两个表的笛卡尔积,返回结果是由第一个表的每行与第二个表的所有行组合后形成的表,因此,数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。交叉连接关键字CROSS JOIN后不跟ON短语引出的连接条件。

符合条件连接:WHERE子句中可以有多个连接条件

SELECT student.sno,sname,sdept,cno,grade FROM student,sc WHERE student.sno=sc.sno and grade<60

3.5,嵌套查询

嵌套查询:将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询

说明:
不相关子查询:子查询与主查询独立, 子查询的查询条件不依赖于父查询,子查询只执行一次。子查询在上一级查询处理之前求解,子查询的结果集用于建立其上一级查询的查找条件。
相关子查询:子查询中涉及主查询的信息,子查询的查询结果依赖于父查询,子查询不只执行一次。
子查询中不能使用ORDER BY子句, ORDER BY只能对最终结果排序。
一个涉及多个表的查询要求,往往既可以用连接查询表达,也可以用嵌套子查询表达 --- 多种方式表达查询。

带有IN谓词的子查询 :由于子查询的结果是纪录的集合,故常使用谓词IN来实现

select SNO from SC where CNO ='1' and SNO in (select SNO from SC where CNO ='2');
列出选修了1号和2号课程的学生的学号

带有比较运算符的子查询 :使用带有比较运算符的子查询,是当用户能确切知道子查询返回的是单值时,可以在父查询WHERE子句中,使用比较运算符进行比较查询。这种查询可以认为是IN子查询的扩展。

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

带有ANY,SOME,ALL关键字的子查询:ALL代表所有值,ALL指定的表达式要与子查询结果集中的每个值都进行比较,当表达式与每个值都满足比较的关系是,才返回TRUE,否则返回FALSE

SOME或ANY代表某些或者某个值,表达式只要与子查询结果集中的某个值满足比较的关系时,就返回TRUE,否则返回FALSE

SELECT * FROM sc WHERE grade>ALL(SELECT grade FROM sc WHERE sno=(SELECT sno FROM student WHERE sname='王小华'))
查询考试成绩比王小华同学高的学生信息。
SELECT * FROM sc WHERE grade >ANY(SELECT grade FROM sc WHERE sno=(SELECT sno FROM student WHERE sname='王小华'))
比王小华同学所有科目的成绩都要高的学生信息

带有EXISTS谓词的子查询:EXISTS称为存在量词,WHERE子句中使用EXISTS表示当子查询的结果非空时,条件为TRUE,反之则为FALSEEXISTS前面也可以加NOT,表示检测条件为“不存在”。EXISTS语句与IN非常类似,它们都根据来自子查询的数据子集测试列的值。不同之处在于,EXISTS使用联接将列的值与子查询中的列联接起来,而IN不需要联接,它直接根据一组以逗号分隔的值进行比较。

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

3.6,集合(联合)查询

集合查询的种类:并集操作UNION;交操作INTERSECT;差操作EXCEPT;

说明:参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同。集合操作自动去除重复元组,如果要保留重复元组的话,必须用ALL关键词指明。如果系统没有提供UNION INTERSECT EXCEPT 运算符, 集合的并、交、差运算也可以用其他方法实现

并:
SELECT * FROM Student WHERE Sdept= 'CS' UNION SELECT * FROM Student WHERE Sage<=19;
SELECT * FROM Student WHERE Sdept =‘CS’ OR Sage<= 19;
查询计算机科学系的学生及年龄不大于19岁的学生并集。
交:
SELECT * FROM Student WHERE Sdept='CS' INTERSECT SELECT * FROM Student WHERE Sage<=19 
SELECT * from  Student WHERE Sdept =‘CS’ AND  Sage<= 19;
查询计算机科学系的学生与年龄不大于19岁的学生的交集。
差:
SELECT * FROM Student  WHERE Sdept='CS' EXCEPT SELECT  * FROM Student WHERE Sage <=19;
SELECT * from   Student WHERE Sdept =‘CS’ AND  Sage> 19;
查询计算机科学系的学生与年龄不大于19岁的学生的差集。/实际上是查询计算机科学系中年龄大于19岁的学生。

UNION和UNION ALL:UNION在进行表求并集后会去掉重复元素,所以会对产生的结果集进行排序运算,删除重复的记录再返回结果。而UNION ALL只是简单地将两个结果合并后返回,速度快。因此,如果返回的两个结果集中有重复的数据,那么返回的结果就会包含重复数据。

4,数据更新

4.1,插入数据

插入元组

INSERT INTO Student(Sno,Sname,Ssex,Sdept,Sage)VALUES('201215128','陈冬','男','IS',18);
将一个新学生元组(学号:201215128;姓名:陈冬;性别:男;所在系:IS;年龄:18岁)插入到Student表中。

插入子查询结果

insert into EXCE(Sno,AVGGrade)select Sno,avg(Grade)from SC group by Sno having avg(Grade)> 90;
将平均成绩大于90的学生加入到EXCE表中。

4.2,更新数据

修改某一个元组的值

UPDATE Student SET Sage=22WHERE Sno='201215121'; 
将学生201215121的年龄改为22岁

修改多个元组的值

UPDATE Student  SET Sage= Sage+1;
将所有学生的年龄增加1岁。

带子查询的修改语句

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

4.3,删除数据

delete和truncate命令都可以用来删除一个表中的数据,它们的区别:

  • truncate是一个数据定义语言(DDL),它会被隐式地提交,一旦执行后将不能回滚。delete执行的过程是每次从表中删除一行数据,同时将删除的操作以日志的形式进行保存以便将来进行回滚操作。
  • 用delete操作后,被删除的数据占用的存储空间还在,还可以恢复。而用truncate操作删除数据后,被删除的数据会立即释放所占的存储空间,被删除的数据不能被恢复。
  • truncate的执行速度比delete快。

删除一个元组

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

删除多个元组

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

带子查询的删除语句

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

4.4,更新操作与数据库一致性

增删改命令一次只能对一个表操作这会带来一些问题 --- 破坏关系数据库的参照完整性。  

系统应保证实体完整性和参照完整性, 可采用策略:

1往参照表(子表)中插入元组时, 系统自动检查被参照表(主表)中是否存在相应的元组, 如果存在则插入操作成功, 否则插入操作失败(称限制插入)

2删除被参照表(主表)中的元组时采用策略:

  系统自动删除参照表(子表)中相应的元组(称级联删除)

  系统检查参照表(子表)中是否存在相应的元组, 如果存在, 则删除操作失败(称限制删除)

5,空值处理

空值:就是“不知道”或“不存在”或“无意义”的值。

存在情况:该属性应该有一个值,但目前不知道它的具体值;该属性不应该有值;由于某种原因不便于填写

空值是一个很特殊的值,含有不确定性。对关系运算带来特殊的问题,需要做特殊的处理

空值的产生:插入或者更新。

空值的判断:name is null; 注意IS不能用‘=’代替, 不能写为name = NULL

空值的约束条件:NOT NULL约束条件的不能取空值;②加了UNIQUE限制的属性不能取空值;码属性不能取空值;

空值的注意事项:如果null参与算术运算,则该算术表达式的值为null如果null参与比较运算,则结果可视为false如果null参与聚集运算,则除count(*)之外其它聚集函数都忽略null

6,视图

6.1,基本概念

视图是从基表中导出的逻辑表,它不像基表一样物理地存储在数据库中,视图没有自己独立的数据实体,它是一个虚拟表。视图作为一种基本的数据库对象,是查询一个表或多个表的另一种方法,通过将预先定义好的查询作为一个视图对象存储在数据库中,然后就可以像使用表一样在查询语句中调用它。

视图的特点:

  • 虚表,是从一个或几个基本表(或视图)导出的表。
  • 只存放视图的定义,不存放视图对应的数据。
  • 基表中的数据发生变化,从视图中查询出的数据也随之改变。
  • 视图之上可以再定义视图。

视图的作用:

  • 视图能够简化用户的操作,简化用户观点。
  • 用户可以通过视图组织自己所关心的数据,不管这些数据来自哪些基本表,是怎么来的,使用户觉得数据库结构简单、清晰、查询操作方便。
  • 视图使不同用户可以从多种不同角度观察同一数据。
  • 视图对重构数据库提供了一定程度的逻辑独立性。
  • 视图能够对机密数据提供安全保护。

6.2,建立视图

CREATE VIEW IS_Student AS (SELECT Sno,Sname,Sage FROM Student WHERE Sdept='IS');
建立信息系学生的视图IS_Student。
CREATE VIEW IS_Student AS (SELECT Sno,Sname,Sage FROM Student WHERE Sdept='IS')WITH CHECK OPTION;
建立信息系学生的视图,并要求进行修改和插入时仍保证该视图只有信息系的学生。
修改操作:RDBMS自动加上Sdept= 'IS'的条件
删除操作:RDBMS自动加上Sdept= 'IS'的条件
插入操作:RDBMS自动检查Sdept属性值是否为'IS' 如果不是,则拒绝该插入操作
如果没有提供Sdept属性值,则自动定义Sdept为'IS'

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

CREATE VIEW BT_S(Sno,Sname,Sbirth)AS SELECT Sno,Sname,2014-Sage FROM  Student;

视图中设置了派生属性列, 这些列在基本表中并不实际存在, 导出视图时通过计算得到。即与视图相应的查询语句的SELECT目标列是表达式。带表达式的视图必须明确定义组成视图的各个属性列名。

6.3,删除视图

drop view 视图名[CASCADE]
该语句从数据字典中删除指定的视图定义
如果该视图上还导出了其他视图,使用CASCADE级联删除语句,把该视图和由它导出的所有视图一起删除 
删除基表时,由该基表导出的所有视图定义都必须显式地使用DROP VIEW语句删除 

6.4,查询视图&更新视图

从用户角度:查询视图与查询基本表相同;更新视图与更新基本表相同;通过视图进行查询没有任何限制,用户可以将注意力集中在其关心的数据上,而非全部数据,这样就大大提高了运行效率与用户满意度。如果数据来源于多个基本表结构,或者数据不仅来自与基本表结构,还有一部分数据来源于其他视图,并且搜索条件又比较复杂,需要编写的查询语句就会比较烦琐,此时定义视图就可以使数据的查询语句变得简单可行。定义视图可以将表与表之间的复杂的操作连接和搜索条件对用户不可见,用户只需要简单地对一个视图进行查询即可,所以,视图虽然增加了数据的安全性,但是不能提高查询的效率。

更新视图:视图看上去非常像数据库的物理表,对它的操作同任何表一样。当通过视图修改时,实际上是在改变表(视图定义中涉及的表)中的数据;相反地,基本数据的改变也会自动反映在由基表产生的视图中。由于逻辑上的原因,有些Oracle视图可以修改对应的基表,有些则不能(仅能查询)。

查询方法&更新方法

  • 实体化视图:有效性检查:检查所查询的视图是否存执行视图定义,将视图临时实体化,生成临时表;查询视图转换为查询临时表;查询完毕删除被实体化的视图(临时表);
  • 视图消解法:进行有效性检查,检查查询的表、视图等是否存在。如果存在,则从数据字典中取出视图的定义;把视图定义中的子查询与用户的查询结合起来,转换成等价的对基本表的查询;执行修正后的查询;

视图更新有限制,要求定义视图时:select子句中的目标列不能包含聚集函数;②select子句中不能使用distinct关键字;③不能包括group by子句;④不能包括经算术表达式计算出来的列;⑤不能从两个以上的基本表中导出;⑥视图定义中不能有嵌套查询

一般来说,对于行列子集视图可以更新,其他视图更新有限制或者不能

更多推荐

数据库:SQL语言,数据查询,数据更新,视图