5.1?SQL简介
结构化查询语言SQL(Structured?Query?Language)是介乎于关系代数和元组演算之间的一种语言。
5.1.1?SQL发展史
5.1.2?SQL数据库的体系结构
SQL数据库的体系结构基本上也是三级结构,但术语与传统的关系模型术语不同。在SQL中,关系模式称为“基本表”(Base?Table),存储模式称为“存储文件”(Stored?File),子模式称为视图(View),元组称为“行”(ROW),属性称为“列”(Column)。
SQL数据库的体系结构要点如下:
(1)一个SQL模式(Schema)是表和约束的集合。
(2)一个表由行集构成,一行是列的序列,每列对应一个数据项。
(3)表有三种类型:基本表、视图和导出表。基本表是实际存储在数据库中的表,视图是由若干基本表或其他视图构成的表的定义,而导出表是执行了查询是产生的表。
(4)一个基本表可以跨一个或多个存储文件,一个存储文件也可以存放一个或多个基本表。每个存储文件与外部存储器上一个物理文件对应。
(5)用户可以用SQL语句对基本表和视图进行查询等操作。在用户看来,两者都是一样的,都是表。
(6)SQL用户可以是应用程序,也可以是终端用户。
5.1.3?SQL的组成
核心SQL主要有四个部分:
(1)数据库定义语言,即SQL?DDL,用于定义SQL模式、基本表、视图、索引等结构。
(2)数据操纵语言。即SQL?DML。
(3)嵌入式SQL语言的使用规定。
(4)数据控制语言,即SQL?DCL。
5.1.4?SQL的特点
5.1.5?SQL的数据定义
5.2.1?SQL模式的创建和撤销
1.SQL模式的创建
在SQL中,一个SQL模式定义为一个基本表的集合。一个SQL模式由模式名和模式所有者的用户名或账号来确定,并包含模式中每一个元素(基本表、视图、索引等)的定义。创建SQL模式,就是定义了一个存储空间。
SQL模式的创建可用CREATE?SCHEMA语句定义,其基本句法如下:
CREATE?SCHEMA?<模式名>?AUTHORIZATION?<用户名>
2.SQL模式的撤销
当一个SQL模式及其所属的基本表、视图等元素都不需要时,可以用DROP语句撤销这个SQL模式。DROP语句的句法如下
DROP?SCHEMA<模式名>?[CASCADE|RESTRICT]
其方式有两种:
CASCADE(级联式)方式:执行Drop语句时,把SQL模式及其下属的基本表、视图、索引等索引元素全部撤销。
RESTRICT(约束式)方式:执行DROP语句时,只有当SQL模式中没有任何下属元素时,才能撤销SQL模式,否则拒绝执行DROP语句。
大多数DBMS把“创建SQL模式”按惯例称为“创建数据库”,语句采用“CREATE?DATABASE...”和“DROP?DATABASE...”
5.2.2?SQL的基本数据类型
SQL允许用户使用“CREATE?DOMAIN”语句定义新的域。定义好域以后,就可以像使用基本类型一样,用域名来定义属性的类型。
5.2.3?基本表的创建和撤销
1.基本表的创建
创建基本表,可用CREATE?TABLE?语句实现
CREATE?TABLE?<基本表名>
(<列名,类型>,
...
<完整性约束>,
......)
表中每个列的类型可以是基本数据类型,也可以是用户预先定义的域名。完整性约束主要有三种子句:主键(PRIMARY?KEY)、外键子句(FOREIGN?KEY)和检查子句(CHECK)。
2.基本表结构的修改
(1)增加新的列用“ALTER?...?ADD?...”语句,其句法如下
ALTER?TABLE<基本表名>?ADD?<列名>?<类型>
应注意,新增加的列不能定义为“NOT?NULL”。基本表在增加一列后,原有元组在新增加的列上的值都被定义为空值(NULL)。
(2)删除原有的列用“ALTER?...DROP...”语句,其句法如下:
ALTER?TABLE?<基本表名>?DROP?<列名>[CASCADE|RESTRICT]
此处CASCADE方式表示:在基本表中删除某列时,所有引用到该列的视图和约束也要一起自动地被删除。而RESTRICT方式表示在没有视图或约束引用该属性时,才能在基本表中删除该列,否则拒绝删除操作。
(3)修改原有列的类型、宽度用“ALTER...?MODIFY...”语句,其句法如下:
ALTER?TABLE?<基本表名>?MODIFY?<列名>?<类型>
3.基本表的撤销
撤销语句的句法如下:
DROP?TABLE?<基本表名>[CASCADE|RESTRICT]
此处CASCADE、RESTRICT的语义同前面句法中的语义一样。
5.2.4?索引的创建和撤销
1.索引的创建
创建索引可用“CREATE?INDEX”语句实现。其句法如下:
CREATE?<UNIQUE>?INDEX<索引名>?ON<基本表名>(<列名序列>)
此处关键字UNIQUE表示每个索引值对应惟一的数据记录。
2.索引的撤销
当索引不需要时,可以用“DROP?INDEX”语句撤销,其句法如下:
DROP?INDEX?<索引名>
5.3?SQL的数据查询
5.3.1?SELECT查询语句的基本结构
1.SELECT句型
SELECT?A1,...,An
FROM?R1,...,Rm
WHERE?F
在WHERE子句中
2.SELECT语句的使用技术
SELECT语句使用时有三种写法:连接查询、嵌套查询和带存在量词的嵌套查询。
查询设计多个基本表时用嵌套结构逐次求解层次分明,具有结构程序设计特点,并且嵌套查询的执行效率也比连接查询的笛卡尔积效率高。在嵌套查询中,IN是常用到的谓词,其结构为“元组IN(集合)”,表示元组在集合内。
5.3.2?SELECT?语句完整的结构
1.聚合函数
SQL提供了下列聚合函数:
COUNT(*) 计算元组的个数
COUNT(<列名>) 对一列中的值计算个数
SUM(<列名>) 求某一列的总和(此列的值必须是数值型)
AVG(<列名>) 求某一列值的平均值(此列的值必须是数值型)
MAX(<列名>) 求某一列值的最大值
MIN(<列名>) 求某一列值的最小值
2.SELECT语句完整的句法
SELECT?语句的完整句法如下:
SELECT?<目标表的列名或列表达式序列>
FROM?<基本表名和(或)视图序列>
[WHERE?<行条件表达式>]
[GROUP?BY?<列名序列>]
[HAVING?<组条件表达式>]
[ORDER?BY?<列名[ASC|DESC]>,...]
句法中[?]表示该成分可有,也可无。
整个语句的执行过程如下:
(1)读取FROM子句中基本表、视图的数据,执行笛卡尔积操作。
(2)选取满足WHERE子句中给出的条件表达式的元组
(3)按GROUP子句中指定列的值分组,同事提取满足HAVING子句中组条件表达式的那些组。
(4)按SELECT子句中给出的列名或列表达式求值输出。
(5)ORDER子句对输出的目标表进行排序,按附加说明ASC升序排列,或按DESC降序排列。
SELECT语句中,WHERE子句称为“行条件子句”,GROUP子句称为“分组子句”,HAVING子句称为“组条件子句”,ORDER子句称为“排序子句”。
5.3.3?数据查询中的限制和规定
1.SELECT子句中的规定
SELECT子句中用于描述查询输出的表格结构,即输出值的列名或表达式,其形式如下:
SELECT[ALL|DISTINCT]?<列名或表达式序列>?|?*
(1)DISTINCT选项保证重复的行将从结果中去除;而ALL选项是默认的,将保证重复的行留在结果中,一般就不必写出。
(2)星号*是对于在FROM子句中命名表的所有列的简写。
(3)列表达式是对于一个单列求聚合之的表达式
(4)允许表达式中出现包含+、-、*和/以及列名、常数的算术表达式。
2.列和基本表的改名操作
有时,用户也可以要求输出的列名与基本表中列名不一致,可在SELECT子句中用“旧名?AS?新名”形式改名。
3.集合的并、交、差操作
当两个子查询结果的结构完全一致时,可以让这两个子查询执行并、交、差操作。并、交、差的运算符为UNION、INTERECT和EXCEPT。
(SELECT?查询语句1)?UNION[ALL]?(SELECT?查询语句2)
(SELECT?查询语句1)?INTERECT[ALL]?(SELECT?查询语句2)
(SELECT?查询语句1)?EXCEPT[ALL]?(SELECT?查询语句2)
上述操作中不带关键字ALL时,返回结果消除了重复元组;而带ALL时,返回结果中未消除重复元组。
5.3.4?条件表达式中的比较操作
1.算术比较操作
2.字符串的匹配操作
添加表达式中字符串匹配操作符是“LIKE”。在表达式中可使用两个通配符:
百分号(%):与零个或多个字符组成的字符串匹配
下划线(_):与单个字符匹配
为了使字符串中包含特殊字符(即%和_),SQL允许定义转义字符。转义字符紧靠特殊字符并放在它前面,表示该特殊字符将被当成普通字符。在LIKE比较中使用ESCAPE关键字来定义转义符。如果使用反斜线(\)作为转义符,那么:
LIKE'ab\%cd%'ESCAPE'\'?匹配所有以“ab%cd”开头的字符串
LIKE'ab\\%cd%'ESCAPE'\'?匹配所有以“ab\cd”开头的字符串
SQL允许使用NOT?LIKE比较运算符搜寻不匹配项。
SQL还允许在字符上使用多种函数,例如连接(“||”)、提取子串、计算字符串长度、大小写转换操作。
3.空值的比较操作
SQL中允许列值为空,空值用保留字NULL表示。
SQL中规定,涉及到+、-、*、/?的算术表达式中有一个值是空值时,表达式的值也是控制,涉及到空值的比较操作的结果认为是“false”。
在聚合函数中遇到空值时,除了COUNT(*)外,都跳过空值而去处理非空值。
4.集合成员资格比较
SQL提供SELECT语句的嵌套子查询机制。子查询是嵌套在另一个查询中的SELECT语句。
判断元组是否在子查询的结果(即集合)中的操作,称为“集合成员资格比较”。其形式如下:
<元组>[NOT]IN(<集合>)
这里的集合可以是一个SELECT查询语句,或者是元组的集合,但其结构应与前面元组的结构相同。IN操作符表示;如果元组在集合内,那么其逻辑值为true,否则为false。
5.集合成员的算术比较
其形式如下:
<元组>θ?ALL?|?SOME?|?ANY?(<集合>)
这里要求“元组”与集合中“元组”的结构一致。θ是算术比较运算符,“θ?ALL”操作表示左边那个元组与右边集合中每一个元组满足θ?运算,“θ?SOME”操作便是左边那个元素组与右边集合中至少一个元组满足θ?运算。ANY和SOME是同义词,早期的SQL标准用ANY,为避免与英语中ANY的意思混淆,后来的标准都改为SOME。
在SQL中,不允许对聚合函数进行复合运算,因此不能写成“SELECT?MAX(AVG(SCORE))”形式。
6.集合空否的测试
可以用谓词EXISTS来测试一个集合是否为非空,或空。其形式如下:
[NOT]EXISTS(<集合>)
不带NOT的操作,当集合非空时(即至少存在一个元组),其逻辑值为true,否则为false。带NOT的操作,当集合为空时,其值为true,否则为false。
7.集合中重复元组存在否的测试
可以用谓词UNIQUE来测试一个集合里是否有重复元组存在。形式如下:
[NOT]UNIQUE(<集合>)
不带NOT的操作,当集合中不存在重复元组时,其逻辑值为true,否则为false。带NOT的操作,当集合中存在重复元组时,其逻辑值为true,否则为false。
<!--EndFragment-->