第三章 关系数据库标准语言SQL
结构化查询语言(Structured Query Language,SQL)是关系数据库的标准语言,也是一个通用的、功能极强的关系数据库语言。
下表为SQL的动词
SQL功能 | 动词 |
---|---|
数据查询 | SELECT |
数据定义 | CREATE,DROP,ALTER |
数据操纵 | INSERT,UPDATE,DELETE |
数据控制 | GRANT,REVOKE |
SQL概述
SQL的基本概念
支持SQL的关系数据库管理系统同样支持关系数据库三级模式结构,如下图所示。
外模式包括若干视图(view)和部分基本表(base table),数据库模式包括若干基本表,内模式包括若干存储文件(stored fire)
用户可以用SQL对基本表和视图进行查询或其他操作,基本表和视图一样,都是关系。
基本表示本身独立存在的表,在关系数据库管理系统中一个关系就对应一个基本表。一个或多个基本表对应一个存储文件,一个表可以带若干个索引,索引也可以放在存储文件中。
存储文件的逻辑结构组成了关系数据库的内模式。存储文件的物理结构对最终用户是隐蔽的。
视图是从一个或几个基本表导出的表。它本身不独立存储在数据库中,即数据库中只存放视图的定义而不存放视图对应的数据。这些数据仍存放在导出视图的基本表中,因此视图是一个虚表。视图在概念上与基本表等同,用户可以在视图上再定义视图。
学生-课程数据库
数据定义
SQL标准不提供修改模式定义和修改视图定义的操作。用户如果想修改这些对象,值能将它们删除然后重建。
一个关系数据库管理系统的实例(instance)中可以建立多个数据库,一个数据库可以建立多个模式,一个模式下通常包括多个表、视图和索引等数据库对象。
模式的定义和删除
略…
CREATE SCHEMA <模式名> AUTHORIZATION <用户名>;
DROP SCHEMA <模式名><CASCADE|RESTRICT>;
注意点:删除模式时,其中CASCADE和RESTRICT两者必选其一。选择了CASCADE(级联),表示在删除模式的同时把该模式中的所有数据库对象全部删除;选择了RESTRICT(限制),表示如果该模式中已经定义了下属的数据库对象(如表、视图等),则拒绝该删除语句的执行。
基本表的定义、删除与修改
略…
建表同时还可以定义与该表有关的完整性约束条件,这些完整性约束条件被存入系统的数据字典中,当用户操作表中的数据时由关系数据库管理系统自动检查该操作是否违背这些完整性约束条件。如果完整性约束条件涉及该表的多个属性列,则必须定义在表级上,否则既可以定义在列级也可以定义在表级。(如一张表有两个主键,那此时主键的定义只能在表级上)
数据类型
关系模型中一个很重要的概念是域。每一个属性来自一个域,他的取值必须是域中的值。
在SQL中域的概念用数据类型来实现。定义表的各个属性时需要指明其数据类型及长度。
一个属性选用哪种数据类型要根据实际情况来决定,一般要从两个方面来考虑,一是取值范围,二是要做哪些运算。
模式与表
每一个基本表属于一个模式,一个模式包含多个基本表。
表的删除需要注意,也包括级联删除和限制删除,和模式的删除类似。在选择级联删除时,如果欲删除的基本表被其他基本表所引用,则这些表也可能被删除。
索引的建立和删除
当表的数据量比较大时,查询操作会比较耗时。建立索引是加快查询速度的有效手段。数据库索引类似图书后面的索引,能快速定位到需要查询的内容。
索引虽然能够加速数据库查询,但需要占用一定的储存空间,当基本表更新时,索引要进行相应的维护,这些都会增加数据库的负担,因此要根据实际应用的需要有选择地创建索引。
删除索引时,系统会同时从数据字典中删去有关该索引的描述。
数据字典
数据查询
SELECT语句中如果没有指定DISTINCT关键字,则默认为ALL,即保留结果表中取值重复的行
下表为常用的查询条件
字符匹配
谓词LIKE可以用来进行字符串的匹配。LIKE后跟着的匹配串可以是一个完整的字符串,也可以含有通配符 % 和 _ 。
- %(百分号)代表任意长度(长度可以为0)的字符串。例如a%b表示以a开头,以b结尾的任意长度的字符串。如acb、addgb、ab等都满足该匹配串。
- _(下横线)代表任意单个字符。例如a_b表示以a开头,以b结尾的长度为3的任意字符串。如acb、afb等都满足该匹配串。
如果LIKE后面的匹配串中不含有通配符,则可以用 =(等于)运算符取代LIKE谓词,用 != 或 <>(不等于)运算符取代NOT LIKE谓词。
注意:数据库字符集为ASCII时一个汉字需要两个_;当字符集为GBK时只需要一个 _。
如果用户要查询的字符串本身就含有通配符 % 或 _ ,这时就需要使用ESCAPE '<换码字符>'短语对通配符进行转义了。
多重条件查询
逻辑运算符AND和OR可用来连接多个查询条件。AND的优先级高于OR,但用户可以用括号改变优先级。
IN谓词实际上是多个OR运算符的缩写~
ORDER BY子句
用户可以用ORDER BY字句对查询结果按照一个或多个属性列的升序(ASC)或降序(DESC)排列,默认值为升序。
对于空值,排序时显示的次序由具体系统实现来决定。例如升序排,含空值的元组最后显示;按降序排,空值的元组则优先显示。各个系统的实现可以不同,只要保持一致就行。
聚集函数
当聚集函数遇到空值时,出COUNT(*)外,都跳过空值而只处理非空值。COUNT( *) 是对元组进行计数,某个元组的一个或部分空值不影响COUNT的统计结果。
注意:WHERE字句中是不能用聚集函数作为条件表达式的。聚集函数只能用于SELECT字句和GROUP BY中的HAVING字句。
GROUP BY字句
GROUP BY字句将查询结果按某一列或多列的值分组,值相等的为一组。
对查询结果分组的目的是为了细化聚集函数的作用对象。如果未对查询结果分组,聚集函数将作用于整个查询结果。分组后聚集函数作用于每一个组,即每一组都有一个函数值。
如果分组后还要求按一定的条件对这些组进行筛选,最终只输出满足指定条件的组,则可以使用HAVING短语指定筛选条件。
WHERE字句与HAVING短语的区别在于作用对象不同。WHERE字句作用于基本表或视图,从中选择满足条件的元组。HAVING短语作用于组,从中选择满足条件的组。
连接查询
前面的查询都是针对一个进行的,也就是单表查询。若一个查询同时涉及两个以上的表,则称之为连接查询。连接查询是关系数据库中最主要的查询,包括等值连接查询、自然连接查询、非等值查询、自身连接查询、外连接查询和复合条件连接查询等。
等值与非等值连接查询
如果属性名在参加连接的各表中是唯一的,则可以省略表名的前缀。
若在等值连接中把目标列中重复的属性列去掉则为自然连接。
自身连接
外连接
左外连接列出左边关系中所有的元组,右外连接列出右边关系中所有的元组。
多表连接
连接操作除了可以是两表连接、一个表与其自身连接外,还可以是两个以上的表进行连接,后者通常称为多表连接。
嵌套查询
注意:子查询的SELECT语句中不能使用ORDER BY字句,ORDER BY字句只能对最终查询结果进行排序。
相比于连接运算,目前商用关系数据库管理系统对嵌套查询的优化做得还不够完善,所以在实际应用中,能够用连接运算表达的查询尽可能采用连接运算。
求解相关子查询不能像求解不相关查询那样一次将子查询求解出来,然后求解父查询。内层查询由于与外层查询有关,因此必须反复求值。
带有ANY(SOME)或ALL谓词的子查询
事实上,用聚集函数实现子查询通常比直接用ANY或ALL查询效率高。ANY、ALL与聚集函数的对应关系如下表所示。
带有EXISTS谓词的子查询
EXISTS代表存在量词。带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。
由于带EXISTS量词的相关子查询只关心内层查询是否有返回值,并不需要查具体值,因此其效率并不一定低于不相关子查询,有时是高效的方法。
集合查询
集合操作主要包括并操作UNION、交操作INTERSECT和差操作EXCEPT。
注意:参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同。
基于派生表的查询
子查询不仅可以出现在WHERE子句中,还可以出现在FROM子句中,这时子查询生成的临时派生表成为主查询的查询对象。
需要说明的是,通过FROM子句生成派生表时,AS关键字可以省略,但必须为派生关系指定一个别名。而对于基本表,别名是可选项。