(译)第三章 SQL介绍

声明:此文章并不是转载或抄袭,是我学习英文版Database System Concepts,Sixth Edition后,写的中文理解,而且后续将会继续发布。目前国内还没有Database System Concepts,Sixth Edition的中文译本,如果所讲内容有雷同,实属巧合,不过文字语言绝对原创。


 SQL介绍


     目前,很多的查询语言在商业或实验中被使用。在本章以及第4、5两章中,我将学习世界上使用最广泛的查询语言,SQL。
     尽管我们所说的SQL语言被称为查询语言,但是它能做的事情不仅仅只是查询数据库。它能够定义数据结构、修改数据和创建安全约束。
     我们的目的不是提供SQL用户指南。相反,我们将展现SQL基本的结构和概念。单个的SQL应用实例在细节方面是有差异的,或者仅仅是SQL语言的一个子集。

3.1 SQL查询语言概述
     19世纪70年代早期,IBM公司开发了SQL的原型,原名是Sequel,是R系统项目的一部分。Sequel语言从那时开始逐步演化,并且它的名称更改为SQL(结构化查询语言)。目前许多产品都支持SQL语言。SQL现在已经成为标准的关系数据库语言。
     1986年,美国国家标准协会(ANSI)和国际标准组织发布了一个SQL标准,命名为SQL-86。ANSI在1989年又发布了一个扩充版的SQL标准,SQL-89.紧接着发布的版本是SQL-92,后来还有SQL:1999,SQL:2003,SQL:2006和最近发布的SQL:2008.附录里面提到了这些标准。
     SQL语言包括如下几个部分:

  • 数据定义语言(DDL),SQL DDL提供了一些指令用于定义关系架构,删除关系和修改关系架构。
  • 数据操纵语言(DML),SQL DML提供了从数据库中检索信息,以及向数据库插入元组、删除元组、修改元组的能力。
  • 完整性,SQL DDL包括创建完整性约束的指令,完整性约束是数据库中的数据必须满足的。不能进行违反完整性约束的更新。
  • 视图定义,SQL DDL包括了定义视图的指令。
  • 事务控制,SQL包括了指定事务开始和结束的指令。
  • 嵌入的SQL和动态SQL,嵌入的和动态的SQL定义了SQL语句如何被嵌入多用途的编程语言中,例如C,C++和Java。
  • 身份认证,SQL DDL包括了指定关系和视图访问权限的指令。

     在这一章中,我们呈现了DML和DDL功能的概览。这里被提到的功能已经是SQL-92的组成部分。
     在第4章中,我们涉及到了SQL语言更广泛、更细致的方面,(a)包括从编程语言中访问SQL的机制;(b)SQL函数和存储过程;(c)触发器;(d)递归查询;(e)高级聚合功能;(f)数据分析功能,出现在SQL:1999和SQL后续的版本中。后面在第22章中,我们概述了面向对象SQL,它出现在SQL:1999中。
     虽然大部分的SQL应用程序支持我们提到的标准功能特性,但是各个SQL应用程序之间有一些区别。很多SQL应用程序支持一些非标准的功能特性,但却不支持一些更高级的功能特性。也许你会发现我们提到一些功能特性在你目前使用的数据库系统中并不支持,查一下用户指南,看看它所提供的功能特性。


3.2 SQL数据定义
     数据库中的关系集必须被定义,可以使用数据定义语言(DDL)来实现。DDL不仅能定义关系集,还可以定义每个关系的详细信息,包括:

  • 关系的架构
  • 属性值的类型
  • 完整性约束
  • 关系的索引集
  • 关系的安全和身份认证
  • 关系在磁盘的物理存储结构

     这里,我们讨论基本的架构定义和基本类型;我们将在第4、5章中讨论其他的DDL功能特性。

3.2.1 基本类型
     SQL有几种内置类型,包括:

  • char(n),固定长度的字符串,长度n由用户指定。也可以使用其全称character表示。
  • varchar(n),可变长度字符串,最大长度n由用户指定。也可以使用全称character varying表示。
  • int,整型(与计算机相关的整数子集)。也可以使用全称integer。
  • smallint,短整型(与计算机相关的整数子集)。
  • numeric(p,d),固定精度的数,精度由用户指定。这个数由p个数字组成,d表示p个数字中在小数点的右边有d位。类型为numeric(3,1)的字段允许存入44.5,而不能存入444.5或者0.32。
  • real,double precision,与计算机精度相关的浮点型和双精度型。
  • float(n),浮点数,如果给出了n,则精度至少为n。

     其他的类型将在4.5节中讨论。
     每个类型的值都可能为null。null表示目前不存在或者未知的值。很快我们将会发现,在某些情况下,我们希望禁止输入null值。
     char数据类型存储固定长度字符串,例如,char(10)类型的属性A。如果我们在属性A中存入"Avi",为了保证10个字符长度,那么将有7个空格填入其末尾。相反,我们在varchar(10)类型的属性B中存入"Avi",就不会有空格填入。在比较两个char类型的值时,如果他们的长度不同,系统将自动用空格补充较段的字符串,然后再进行比较。
     当比较char类型和varchar类型时,为了长度相同,我们可能希望能将空格填充到varchar类型的末尾。或许能自动填充,或许不能,这依赖于数据库系统本身。因此,即使在属性A和属性B中同样存入了"Avi",A=B的结果仍然是false。为了避免这个问题,推荐大家总是用varchar类型代替char类型。
     SQL还提供了nvarchar类型来存储Unicode格式的多语言数据。虽然如此,许多数据库还是允许在varchar类型中存储Unicode(UTF-8)格式的数据。

3.2.2 基本架构定义
     SQL中使用create table指令来定义关系。下面的指令在数据库中创建了一个名为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指令的一般格式如下:
        create table r
          (A1 D1,
           A2 D2,
           ...,
           An Dn,
           <integrity-constraint1>,
           ...,
           <integrity-constraintk>);
r是关系的名称,Ai是关系r的属性,Di是属性Ai的域,Di指出了属性Ai的类型,以及Ai所有可能出现的值的范围。
create table语句末尾出现的分号以及在本章其他SQL语句末尾出现的分号,表示该SQL语句结束了,但是在许多SQL实例中,分号是可选的。
SQL中有很多完整性约束,这里我们仅讨论一部分:

  • primary key(Aj1,Aj2,...,Ajm):primary-key详细列表表明属性Aj1,Aj2,...,Ajm组成了关系的主键。主键属性具有非空性和唯一性。意思就是,任何元组在主键属性上的值都不能为null,并且关系中任意两个元组之间的主键属性值不能一样。尽管主键是可选的,但是一般来说,给每个关系指定一个主键是非常有用的。
  • foreign key(Ak1,Ak2,...,Akn) references s:foreign key详细列表表明关系中任意元组的属性(Ak1,Ak2,...,Akn)值都必须对应于关系s中某个元组的主键属性值。
  • 图3.1给出了我们在本书中所举例的大学数据库的SQL DDL定义。course表的定义中包含了对department的外键引用。外键引用表明,在course元组中被引用的每一个学院名称必须存在于department关系的主键属性值中。如果没有这个约束,一个课程可能会使用一个不存在的学院。图3.1也给出了表section,instructor和teaches的外键约束。
  • not null:属性的not null约束表明该属性中不允许存在null值。换句话说,该约束从属性的值域中排除了null值。例如,图3.1,关系instrutor的属性name拥有not null约束,那就意味着必须给出每位教授的名字。

     我们将在4.4中更详细地讲解create table指令中的外键以及其他完整性约束。
     SQL严禁任何破坏数据库完整性约束的更新。例如,新插入的元组或被修改的元组,设置其主键值为null,或者其主键值与其他元组主键值相同,这时候SQL将提示错误并停止更新。因此,在course插入一个元组,该元组的dept_name却未出现在department关系中,将会破坏course上的外键约束,此时SQL会停止插入操作。
     新创建的关系,初始化为空,即没有任何元组。 我们可以使用insert指令来写入数据。例如,我们想插入一条真是数据,有一个教授,名叫Smith,所在学院是Biology,instructor_id为10211,工资66000美元,这个语句写法如下:
        insert into instructor
            values(10211,'Smith','Biology',66000) ;
     按顺序列出的值与关系架构中的属性一一对应。insert指令有很多用处,我们将在3.9.2中更详细的讲解。
     使用delete指令能够从关系中删除元组。下面的指令将会删除关系student中所有的元组。其他格式的delete指令还可以删除某些指定的元组,将在3.9.1节中更详细的讲解delete指令。
        delete from student;
     我们使用drop table指令从数据库中删除关系,drop table将从数据库删除关系的一切信息,指令
        drop table r;
     更彻底于指令
        delete from r;
     后者仍然保留关系r,只是删除其中所有元组,前者不仅仅只删除所有元组,也将删除关系的架构。在关系r被删除后,不能再向其插入元组,除非使用create table指令重建关系r。
     使用alter table指令对已经创建的关系增加新的属性。关系中所有的元组在新属性上都被指定为null值。alter table指令的格式如下:
        alter table r add A D;
     r指关系的名称,A是新属性的名称,D是新属性的数据类型。我们还可以用下面的指令从关系中删除属性
        alter table r drop A;
     r指关系的名称,A是将被删除的属性名。许多数据库系统支持删除整个表,却不支持删除属性。

未完待续...

posted @ 2012-02-03 18:09  预备程序员  阅读(1046)  评论(0编辑  收藏  举报