Contents
● 商业性使用或实验性使用的数据库査询语言有好几种。学习使用最为广泛的査询语言: SQL 。
● 尽管我们说 SQL 语言是一种“查询语言”,但是除了数据库查询,它还具有很多别的功能,它可以定义数据结构、修改数据库中的数据以及说明安全性约束条件等。
● 我们的目的并不是提供一个完整的 SQL 用户手册,而是介绍 SQL 的基本结构和概念。 SQL 的各种实现可能在一些细节上有所不同,或者只支持整个语言的一个子集。
3.1 SQL 查询语言概览
● SQL 最早的版本是由 IBM 开发的,它最初被叫做 Sequel ,在20世纪70年代早期作为 System R 项目的一部分。 Sequel 语言一直发展至今,其名称已变为 SQL (结构化查询语言)。现在有许多产品支持 SQL 语言, SQL 已经很明显地确立了自己作为标准的关系数据库语言的地位。
● 1986年美国国家标准化组织( ANSI )和国际标准化组织( ISO )发布了SQL 标准: SQL -86。
● 1989年 ANSI 发布了一个 SQL 的扩充标准: SQL -89。该标准的下一个版本是 SQL -92标准,接着是 SQL :1999, SQL :2003, SQL :2006,最新的版本是 SQL :2008。
●SQL 语言有以下几个部分:
• 数据定义语言( Data - Definition Language , DDL ): SQLDDL 提供定义关系模式、删除关系以及修改关系模式的命令。
• 数据操纵语言( Data - Manipulation Language , DML ): SQL DML 提供从数据库中查询信息,以及在数据库中插人元组、删除元组、修改元组的能力。
• 完整性( integrity ): SQL DDL 包括定义完整性约束的命令,保存在数据库中的数据必须满足所定义的完整性约束。破坏完整性约束的更新是不允许的。
• 视图定义( view definition ): SQL DDL 包括定义视图的命令。
• 事务控制( transaction control ): SQL 包括定义事务的开始和结束的命令。
• 嵌入式 SQL 和动态 SQL ( embedded SQL and dynamic SQL ):嵌人式和动态 SQL 定义 SQL 语句如何嵌人到通用编程语言,如 C 、 C ++和 Java 中。
• 授权( authorization ): SQL DDL 包括定义对关系和视图的访问权限的命令。
● 对 SQL 的基本 DML 和 DDL 特征的概述。在此描述的特征自 SQL -92以来就一直是 SQL 标准的部分。
3.2 SQL 数据定义
数据库中的关系集合必须由数据定义语言( DDL )指定给系统。 SQL 的 DDL 不仅能够定义一组关系,还能够定义每个关系的信息,包括:
●每个关系的模式。
●每个属性的取值类型。
●完整性约束。
●每个关系维护的索引集合。
●毎个关系的安全性和权限信息。
●每个关系在磁盘上的物理存储结构。
在此只讨论基本模式定义和基本类型
3.2.1基本类型
SQL 标准支持多种固有类型,包括:
● char ( n ):固定长度的字符串,用户指定长度 n 。也可以使用全称 character 。
● varchar ( n ):可变长度的字符串,用户指定最大长度 n ,等价于全称 character varying 。
● int ;整数类型(和机器相关的整数的有限子集),等价于全称 integer 。
● smallint :小整数类型(和机器相关的整数类型的子集)。
● numeric ( p , d ):定点数,精度由用户指定。这个数有 p 位数字(加上一个符号位),其中 d 位数字在小数点右边。所以在一个这种类型的字段上, numeric (3,1)可以精确储存44.5,但不能精确存储444.5或0.32这样的数。
● real , double precision :浮点数与双精度浮点数,精度与机器相关。
● float ( n ):精度至少为 n 位的浮点数。
● 每种类型都可能包含一个被称作空值的特殊值。空值表示一个缺失的值,该值可能存在但并不为人所知,或者可能根本不存在。在可能的情况下,我们希望禁止加人空值,正如我们马上将看到的那样。
● char 数据类型存放固定长度的字符串。
● 例如,属性 A 的类型是 char (10)。如果我们为此属性存人字符串“ Avi ”,那么该字符串后会追加7个空格来使其达到10个字符的串长度。反之,如果属性 B 的类型是 varchar (10),我们在属性 B 中存人字符串“ Avi ”,则不会增加空格。
● 当比较两个 char 类型的值时,如果它们的长度不同,在比较之前会自动在短值后面加上额外的空格以使它们的长度一致。
● 当比较一个 char 类型和一个 varchar 类型的时候,也许读者会期望在比较之前会自动在 varchar 类型后面加上额外的空格以使长度一致;然而,这种情况可能发生也可能不发生,这取决于数据库系统。其结果是,即便上述属性 A 和 B 中存放的是相同的值“ Avi ”, A = B 的比较也可能返回假。
● 我们建议始终使用 varchar 类型而不是 char 类型来避免这样的问题。
● SQL 也提供 nvarchar 类型来存放使用 Unicode 表示的多语言数据。然而,很多数据库甚至允许在 varchar 类型中存放 Unicode (采用 UTF -8表示)。
3.2.2 基本模式定义
用create table 命令定义SQL关系,下面的命令在数据库中创建了一个department 关系:
create table department
(dept name varchar (20),
building varchar (15),
budget numeric (12,2),
primary key (dept name));
上面创建的关系具有三个属性,dept_name是最大长度为20的字符串,building 是最大长度为15 的字符串,budget 是一个12位的数,其中2位数字在小数点后面。create table命令还指明了dept_name 属性是department关系的主码;
create table 命令的通用形式是:
integrity-constraint :完整性约束
其中r 是关系名,每个Ai 是关系r 模式中的一个属性名,Di是属性Ai的域,也就是说Di 指定了属性Ai的类型以及可选的约束,用于限制所允许的Ai取值的集合;
create table 命令后面用分号结束;
SQL支持许多不同的完整性约束,其中少数几个如下:
● primary key ( A j1, Aj2 ,…, Ajm ): primary - key 声明表示属性 A j1, Aj2 ,…, Ajm 构成关系的主码。主码属性必须非空且唯一,也就是说没有一个元组在主码属性上取空值,关系中也没有两个元组在所有主码属性上取值相同。虽然主码的声明是可选的,但为每个关系指定一个主码通常会更好。
● foreign key ( Ak1 , Ak2 ,…, Akm) references : foreign key 声明表示关系中任意元组在属性( Ak1 , Ak2 ,…, Akm)上的取值必须对应于关系 s 中某元组在主码属性上的取值。
图3-1给出了我们在书中使用的大学数据库的部分 SQL DDL 定义。 course 表的定义中声明了“ foreign key ( dept _ name ) references department "。此外码声明表明对于毎个课程元组来说,该元组所表示的系名必然存在于 department 关系的主码属性( dept _ name )中。没有这个约束的话,就可能有某门课程指定了一个不存在的系名。图3-1还给出了表 section 、 instructor 和 teaches 上的外码约束。
create table department
(dept_name varchar (20),
building varchar (15),
budget numeric (12,2),
primary key (dept_name));
create table course
(course_id varchar (7),
title varchar (50),
dept_name varchar (20),
credits numeric (2,0),
primary key (course_id),
foreign key (dept_name) references department);
create table instructor
(ID varchar (5),
name varchar (20) not null,
dept_name varchar (20),
salary numeric (8,2),
primary key (ID),
foreign key (dept_name) references department);
create table section
(course_id varchar (8),
sec_id varchar (8),
semester varchar (6),
year numeric (4,0),
building varchar (15),
room_number varchar (7),
time_slot_id varchar (4),
primary key (course_id, sec_id, semester, year),
foreign key (course_id) references course);
create table teaches
(ID varchar (5),
course_id varchar (8),
sec_id varchar (8),
semester varchar (6),
year numeric (4,0),
primary key (ID, course_id, sec_id, semester, year),
foreign key (course_id, sec_id, semester, year) references section,
foreign key (ID) references instructor);
● not null :一个属性上的 not null 约束表明在该属性上不允许空值。换句话说,此约束把空值排除在该属性域之外。
例如在图3-1中, instructor 关系的 name 属性上的 not null 约束保证了教师的姓名不会为空。
● SQL 禁止破坏完整性约束的任何数据库更新。
例如,如果关系中一条新插人或新修改的元组在任意一个主码属性上有空值,或者元组在主码属性上的取值与关系中的另一个元组相同, SQL 将标记一个错误,并阻止更新。
类似地,如果插人的 course 元组在 dept _ name 上的取值没有出现在 department 关系中,就会破坏 course 上的外码约束, SQL 会阻止这种插人的发生。
● 一个新创建的关系最初是空的。我们可以用 insert 命令将数据加载到关系中。例如,如果我们希望插入如下事实:在 Biology 系有一个名叫 Smith 的教师,其 instructor _ id 为10211,工资为66000美元,可以这样写:
insert into instructor values (10211, ’Smith’, ’Biology’, 66000);
值被给出的顺序应该遵循对应属性在关系模式中列出的顺序;
● 使用 delete 命令从关系中删除元组。命令:
delete from student ;
将从 student 关系中删除所有元组。其他格式的删除命令允许指定待删除的元组;
如果要从 sQL 数据库中去掉一个关系,我们使用 drop table 命令。 drop table 命令从数据库中删除关于被去掉关系的所有信息。命令:
drop table r ;
是比
delete from r ;
更强的语句。后者保留关系 r ,但删除 r 中的所有元组。前者不仅删除 r 的所有元组,还删除 r 的模式。一旦 r 被去掉,除非用 create table 命令重建 r ,否则没有元组可以插人到 r 中。
● 使用 alter table 命令为已有关系增加属性。关系中的所有元组在新属性上的取值将被设为 null 。 alter table 命令的格式为:
alter table r add A D ;
其中 r 是现有关系的名字, A 是待添加属性的名字, D 是待添加属性的域。
可以通过命令
alter table r drop A ;
从关系中去掉属性。其中 r 是现有关系的名字, A 是关系的一个属性的名字。很多数据库系统并不支持去掉属性,尽管它们允许去掉整个表。
3.3 SQL查询的基本结构
SQL查询的基本结构由三个子句构成:select 、from 和where;查询的输入是在from子句中列出的关系,在这些关系上进行where