SQL学习指南(第2版)(修订版)(txt+pdf+epub+mobi电子书下载)


发布时间:2020-05-12 16:47:11

点击下载

作者:[美]博利厄(Alan Beaulieu)著

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

SQL学习指南(第2版)(修订版)

SQL学习指南(第2版)(修订版)试读:

前言

编程语言在不断地出现和消亡,现在使用的语言只有很少一部分的历史能追溯到20年前。其中有大量应用在大型机环境的Cobol和流行于操作系统、服务器开发以及嵌入式系统的C语言。而在数据库领域,SQL的根源可以追溯到19世纪70年代。

SQL是一种从关系型数据库生成、操作和检索数据的语言。关系型数据库流行的原因之一是正确设计的关系型数据库可以处理海量数据。但处理大量数据集时,SQL就像一个高功率可变焦距的时髦数码相机,让你能够看到大型数据集,或者放大单独的行(或者两者之间的任何地方)。其他的数据库管理系统在沉重的负荷下往往会由于它们的焦距太窄(缩放镜头已经处于最大位置了)而崩溃,这就是要废黜关系型数据库和SQL的尝试已经基本上失败了的原因。因此,即使SQL是一门古老的语言,它也将继续活跃很长一段时间,并且在存储应用方面有光明的前途。为什么要学习SQL

如果打算使用关系型数据库,无论是写应用程序、执行管理任务还是生成报表,那么都需要知道如何与数据库中的数据交互。即使使用工具为自己生成SQL,比如报表工具,有时也需要绕过自动生成功能而编写自己的SQL语句。

学习SQL语言有一个额外的好处,即强迫你勇敢面对并学会理解用于储存自己组织相关信息的数据结构。当开始适应数据库的表时,你可能会发现自己也会产生对数据库进行修改或增加等的建议。为什么使用本书学习SQL

SQL语言可分为几类:用于创建数据库对象(表、索引、约束等)的语句统称为SQL模式语句,而用于创建、操纵和检索保存在数据库中的数据的语句称为SQL数据语句。作为管理员,你将同时使用SQL模式和SQL数据语句,而程序员或者报表作者可能只需要使用(或者只允许使用)SQL数据语句。虽然本书介绍了许多SQL模式语句,但是主要焦点还是编程功能。

由于只有少数命令,因此SQL数据语句看似很简单。依我看来,现在许多SQL图书都通过仅仅涉猎这个语言可能的表层知识帮助你培养这种观念。然而,如果打算使用SQL,那么你就有必要充分理解它的语言能力以及如何组合不同的功能以产生强大的结果。我感觉本书是唯一一本详细介绍SQL语言而不会同时被作为门挡的书(正如我知道的,1250页的“完全手册”往往被丢在人们的卧室书架上,布满了灰尘)。

虽然本书的示例都可以运行在MySQL、Oracle数据库以及SQL Server上,但是我必须选择其中之一来作为示例数据库服务器并规范化示例查询返回的结果集。我在这3个产品中选择了MySQL,是因为它可以免费获得、安装简单以及易于管理。对于那些使用其他服务器的人,我建议下载和安装MySQL并加载示例数据库,这样就可以运行示例数据库并试验数据了。本书的结构

本书分为15章和3个附录。

第1章“背景知识”,探讨计算机数据库的历史,其中包括关系模型以及SQL语言的出现。

第2章“创建和操作数据库”,说明如何创建本书示例使用的MySQL数据库和表,以及用数据填充表。

第3章“查询入门”,介绍选择语句,然后进一步阐述了大多数常用子句(select、from、where)。

第4章“过滤”,说明不同类型的条件,它们可以用于select、update或delete语句的where子句中。

第5章“多表查询”,展示如何通过表的连接使用多表进行查询。

第6章“使用集合”,介绍所有关于数据集的知识以及它们如何在查询内交互。

第7章“数据生成、转换和操作”,说明用于操作或转换数据的几个内置函数。

第8章“分组与聚集”,展示如何聚合数据。

第9章“子查询”,介绍子查询(个人最喜欢的),并说明如何以及在何处使用它们。

第10章“再谈连接”,更加深入地讨论不同类型的表连接。

第11章“条件逻辑”,探讨如何在select、insert、update和delete语句里使用条件逻辑(如if-then-else)。

第12章“事务”,介绍事务及如何使用它们。

第13章“索引和约束”,探讨索引和约束。

第14章“视图”,说明如何构建接口以屏蔽数据复杂性。

第15章“元数据”,说明数据字典的使用。

附录A“示例数据库的ER图”,展示本书所有示例的数据库模式。

附录B“MySQL对SQL语言的扩展”,说明在MySQL的SQL实现中一些有趣的非ANSI功能。

附录C“练习答案”,介绍各章习题的答案。阅读须知

本书使用了下面的印刷约定:提示 指出提示、建议或者一般注意性的问题。例如,我使用注意向你表明Oracle 9i的新功能。警告 指示一个告诫或提醒。例如,我告诉你如果不小心使用,那么有些SQL语句可能会产生意想不到的后果。联系我们

请将对本书的评论和问题按以下地址与出版社联系。

美国:O’Reilly Media, Inc.

1005 Gravenstein Highway North

Sebastopol, CA 95472

中国:100035北京市西城区西直门成铭大厦C座807室

奥莱利技术咨询(北京)有限公司

O’Reilly为本书维护了一个网页,列出了勘误表、范例以及任何其他信息。可以通过以下地址访问:

http://www.oreilly.com/catalog/9780596520830

要询问技术问题或提出建议,请发邮件至:

bookquestions@oreilly.com

info@mail.oreilly.com.cn

更多关于O’Reilly的图书、会议信息、资源中心以及O’Reilly网络,请访问以下网页:

http://www.oreilly.com

http://www.oreilly.com.cn使用示例代码

本书是为了帮助你完成工作。一般情况下,你可以在程序和文档中使用本书的代码。如果你使用本书的重要代码,不必联系我们获取许可。例如,使用本书中几大块代码写自己的程序不需要获得许可,但是如果要将O’Reilly书籍中的用例制作成光盘出售或发布,则必须获得许可。引用本书内容或范例解决其他问题不需要获得许可,但是如果想在你的产品文档中包含本书中一些重要的示例代码,那么也需要得到许可。

如果引用了本书内容,那么我们很感激你标明出处,但并不做要求。出处通常包括标题、作者、出版商以及ISBN。例如,“Learning SQL, Second Edition, by Alan Beaulieu. Copyright 2009 O’Reilly Media, Inc., 978-0-596-52083-0.”。

如果你并不清楚使用本书示例代码是否侵权,请随时与我们联系:

permissions@oreilly.com致谢

首先我想感谢编辑Mary Treseler,因为她的帮助使第2版成为现实,其次,再次感谢Kevin Kline、Roy Owens、Richard Sonen和Matthew Russell,是他们在圣诞节和新年时还在审查本书。我还想感谢第1版的一些读者,他们提出了很多问题、建议和勘误。最后,感谢我的妻子Nancy、女儿Michelle和Nicole,是她们给了我很多鼓励和启发。作者简介

Alan Beaulieu从事设计、构建和实现应用数据库已有15个年头,他目前经营自己的顾问公司,专门提供金融和电信领域的Oracle数据库设计与支持服务。Alan使用了Oracle的诸多特性,如并行查询、分区和并行服务器等,以构建OLTP和OLAP环境下的大型数据库。Alan获得了康奈尔大学工程学院的运筹学学士学位,现在和妻子以及两个女儿一起住在马萨诸塞州,可以通过电子邮箱albeau_mosql@yahoo.com与他联系。封面介绍

本书封面上的动物是安第斯有袋树蛙,它的名字暗示了这种在傍晚和夜间活动的青蛙原生地在安第斯山脉的西坡,并且广泛分布在北部的里奥班巴盆地和伊瓦拉之间。

在求偶期,雄蛙发出“哇可-啊可-啊可”的叫声以吸引雌蛙,如果一只怀孕中的雌蛙被吸引过来,雄蛙将会爬到它的背上执行常见的青蛙交配过程。当雌蛙从泄殖腔中排出卵时,雄蛙用脚抓住这些卵并完成受精,然后将它们放到雌蛙的孵化袋中。雌蛙一次可以孵化130多枚蛙卵,这些卵需要在它的孵化袋中发育60~120天。 在孵化期间,雌蛙的身体将会变得臃肿,并且在它背部皮下将会出现许多肿块。当卵在孵化袋中发育成蝌蚪时,雌性树蛙将它们放入水中。两三个月之后,这些蝌蚪将会变成青蛙,而在7个月之后,它们进入了生育期,又开始“哇可-啊可-啊可”了。

雄性和雌性树蛙的前后趾上都进化出许多吸盘,这可以用来帮助它们攀爬树木等垂直的表面。成年雄蛙大小为2英寸左右(约5cm),而雌蛙为2.5英寸(6.35cm)。它们的表皮有时为绿色,有时为褐色,有时为这两种颜色的混合色,幼年期的树蛙在生长时会逐渐由褐色变为绿色。

封面图片来自于Dover Archive Pictorial(《多佛尔档案画报》)。第1章 背景知识

在我们开始学习本书的内容时,先了解一些数据库方面的基本概念及计算机数据存储和检索的发展史是十分有益的。1.1 数据库简介“数据库”是指一组相关信息的集合。例如,电话簿就可以被视为包含某地区所有居民的姓名、电话号码、地址等信息的数据库。尽管电话簿可能是一个最为普及和常用的数据库,但它仍有不少缺点,比如:● 查找某人的电话号码相当费时,特别是在电话簿包含了海量条目

时;● 电话簿只是根据姓名来索引,因此对于根据特定地址查找居民姓

名就无能为力了;● 当电话簿被打印后,随着该地区居民的流动、更改电话号码或住

址等行为不断发生,电话簿上的信息也变得越来越不准确。

电话簿的这些缺陷同样存在于任何人工编制的数据存储系统,比如存放在档案柜的病历等。由于这些纸质数据库不方便,因此最早的计算机应用之一就是开发数据库系统,即通过计算机来存储和检索数据的机制。因为数据库系统通过电子而不是纸质方式来存储数据,所以它可以更快速地检索数据、以多种方式索引数据以及为其用户群提供最新的信息。

早期的数据库系统将被管理的数据存储在磁带上。一般情况下磁带的数量比磁带机要多得多,因此在请求数据时需要技术人员手动装卸磁带。同时由于那个时代的计算机内存很小,通常对同一数据的并发请求必须多次读取磁带,降低了使用效率。因此尽管这些数据库系统相对于纸质数据库有了显著的进步,但与今天的数据库技术相比仍有相当遥远的差距。(现代数据库系统能够利用海量快速的磁盘驱动器来管理太字节级的数据,在高速内存中存放数十吉字节的数据。)1.1.1 非关系数据库提示 本小节讨论早期非关系数据库的背景信息,如果读者急于学习SQL,可以跳过下面几页,直接阅读下一章节。

在计算机数据库发展的前几十年里,数据以各种不同的方式存储并展现给用户。例如,在层次数据库系统中,以一个或多个树形结构来表示数据。图1-1显示了以树形结构表示的George Blake和Sue Smith的银行账户数据。图1-1 账户数据的层次视图

George和Sue的数据树都包含了各自的账户以及交易信息。层次数据库系统提供了定位客户信息树的工具,并能够遍历此树找到所需要的账户或交易数据。树中的每个节点都具有0个或1个父节点,以及0个、1个或多个子节点。这种设置被称为单根层次结构(single-parent hierarchy)。

另一种管理数据的方式是网状数据库系统,它表现为多个记录集合,集合之间通过链接来定义不同记录间的关系。图1-2显示了使用此系统表示的George和Sue的账户信息。

在此系统中,为了查找Sue的MoneyMkt账户上的交易信息,需要执行下面的步骤:

1.查找Sue Smith的客户记录;

2.通过链接从Sue Smith的客户记录找到其账户列表;

3.遍历账户列表直至找到MoneyMkt账户;图1-2 账户数据的网状视图

4.通过链接从MoneyMkt账户找到其交易列表。

网状数据库系统的有趣特性体现在图1-2中最右侧的products记录。注意每个product记录(Checking、Savings等)都指向一个account记录列表,以指定这些账户记录的产品类型。因此account记录可以通过多个入口进行访问(customer记录或product记录),这使得网状数据库具有多根层次的特点。

层次和网状数据库仍然存在,尽管主要在大型机领域中使用。此外,层次数据库系统与可扩展标记语言(XML)相结合,在目录服务方面获得了新的应用,比如Microsoft公司的Active Directory和Red Hat的Directory Server。然而,从20世纪70年代开始,一种新的表示数据的方式逐步扎根并获得发展,这种方式更为严谨,且易于理解和实现。1.1.2 关系模型

1970年,IBM研究院的E.F.Codd博士发表了一篇名为“大型共享数据银行的数据关系模型”的论文,提出使用表集合来表示数据,但相关条目之间并不使用指针来导航,而是借助冗余数据来链接不同表中的记录。图1-3显示了此方法所表示的George和Sue的账户信息。图1-3 账户数据的关系视图

图1-3中包含了4个记录表:Customer、Product、Account和Transaction。首先查看图中顶部的Customer表,其中具有3列:cust_id(其中包含客户的ID号)、fname(其中包含客户的名字)和lname(其中包含客户的姓氏)。Customer表中包含了两个记录行,分别为Georage Blake和Sue Smith的数据。在不同的数据库管理服务器中,记录表可包含的最大列数是有差异的,但通常这个数目足够大而不需要为此担心(比如Microsoft的SQL Server允许每张表可以最多具有1024列)。表中数据行的数目通常只是受到物理设备(磁盘空间大小)和可维护性(在表中记录数在到达多大规模之后仍能保持易用性)的限制,而数据库管理服务器一般不对此进行限制。

关系数据库中的每张表都包含一项作为每行唯一标识的信息(主键),它与其他信息一起构成了对条目的完整描述。对于Customer表,cust_id列为每个顾客保存了不同的编号。例如,George Blake可以由顾客 ID#1来唯一标识,其他顾客则永远不会被赋予此标识符。因此在Customer表中,不再需要其他信息来定位George Blake的数据。提示 每种数据库服务器都提供用于产生一组作为主键值的唯一数字的机制,因此用户不需要为哪些数字已被赋予为主键而操心。

当然也可以选择联合使用fname和lname两列作为主键(包含两列或多列的主键通常被称为复合主键),实际上,在银行账户中很可能会出现两个或多个人具有完全相同的姓氏和名字。因此,选择cust_id列专门用于Customer表的主键是更合适的做法。提示在本例中,选择fname/lname作为主键,称之为自然主键;使用cust_id作为主键,则称为逻辑主键。使用哪一种主键更好一直是悬而未决的热门讨论问题,但在本例中的选择是显而易见的,因为人们的姓名可能发生改变(比如某人结婚后使用其配偶的姓氏),而主键列在被赋值后是绝不允许被修改的。

一些表中还包含了导航到其他表的信息,即前文提到的“冗余数据”。举例来说,Account表中的cust_cd列,它包含了使用该账户的顾客的唯一性标识,而product_id列则包含了该账户所关联产品的唯一性标识。这些列被称为外键,用于作为账户信息网络结构中的各实体之间的连线。如果需要查询某个账户所有者的相关信息,则需要获取cust_id列的值,并使用它在Customer表中查找相应的行(在关系数据库术语中,此过程被称为连接(join),在第3章基本查询对此进行了介绍,并在第5章和第10章进行了更深入的讨论)。

也许多次存储同样的信息是一种浪费的做法,但是某些情况下使用冗余数据能够更清晰地体现关系模型。例如,在Account表中包含一个该账户所有者的唯一标识符是合适的,如果在Account表中再增加顾客的fname/lname列就不太恰当了,这会使数据库中的数据不再可靠。因为放置该数据(顾客的姓/名)的地方应当是Customer表,并且该表中只有cust_id列才适合在其他表中被引用。此外,在一列中包含多条信息也是不合适的,比如使用name列同时包含顾客的姓和名,或者使用address列包含街道、城市、省以及邮政编码等信息。数据库设计精化过程的主要目标就是保证每条独立的信息只存放在一个地方(外键除外),称为规范化。

返回到图1-3中的4个表,或许你会疑惑如何使用这些表来查找George Blake在他的checking账户上的交易信息。首先,在Customer表中找到George Blake的唯一性主键。然后,在Account表中找到cust_id列等于George的唯一性标识符,并通过Product_cd匹配Product表中name列为“Checking”的那些行。最后,通过匹配Account表的唯一性标识account_id列来定位Transaction表中相对应的行。这些看起来有些复杂,但你很快就会发现,在SQL语言中,使用一个命令就足以完成这些任务了。1.1.3 一些术语

在前面已经介绍了一些新的术语,下面介绍一些正式的定义,表1-1显示了本书余下部分所使用术语的定义。表1-1 术语和定义术语定  义数据库用户所关注的对象,如顾客、部门、地理位置实体等列存储在表中的独立数据片段所有列的一个集合,完整地描述了一个实体或实体上行的某个行为,也称之为记录行的集合,既可以保存在内存中(未持久化),也可以表保存在存储设备中(已持久化)结果集未持久化表的另一个名字,一般为SQL查询的结果主键用于唯一标识表中每个行的一个或多个列外键一个或多个用于识别其他表中某一行的列1.2 什么是SQL

根据Codd对关系模型的定义,他提出一种名为DSL/Alpha的语言,用于操控关系表的数据。在Codd的论文发表后不久,IBM建立了一个研究小组来根据他的想法构建原型。该小组创建了一个DSL/Alpha的简化版本,即SQUARE,然后通过对SQUARE的改进,将之发展为SEQUEL语言,并最终命名为SQL。

今天SQL已经发展到了中年期(唉,就像作者一样),在这期间它经历了大量修改。在20世纪80年代中期,美国国家标准组织(ANSI)开始制定SQL语言的第一个标准,并于1986年发布。其后不断对其改进,并在1989年、1992年、1999年、2003年和2006年发布了一系列SQL标准的新版本。通过对语言核心的改良,新的特性被陆续加入到SQL语言中,以吸收面向对象等其他功能。最后一个标准版本,SQL 2006则聚焦于SQL和XML的集成,并定义了XQuery语言以用于在XML文档中查询数据。

SQL与关系模型的关系密切,因为SQL查询的结果也可以视为一张表(在程序上下文中称之为结果集)。因此,可以在关系数据库中简单地创建一个固定表,用于存放查询的结果集。同样地,SQL查询也可以使用固定表或其他查询的结果集作为其输入(在第9章中将会讲述其细节)。

最后需要注意的一点是:SQL并不是任何短语的缩写(尽管许多人坚持认为它代表结构化查询语言(Structured Query Language))。当提到此语言时,可以使用独立的字母(S.Q.L)或使用单词sequel。1.2.1 SQL语句的分类

在本书中,将分别讨论SQL语言的几个独立模块,即SQL 方案(schema)语句,用于定义存储于数据库中的数据结构;SQL数据语句,用于操作SQL方案语句所定义的数据结构;以及SQL事务语句,用于开始、结束或回滚事务(将在第12章中介绍)。例如,在数据库中创建新表时,需要使用SQL方案语句create table,而在新表中产生数据则需要SQL数据语句insert。

下面给出这些语句的具体例子,用于创建corporation表的SQL方案语句如下:CREATE TABLE corporation (corp_id SMALLINT, name VARCHAR(30), CONSTRAINT pk_corporation PRIMARY KEY (corp_id) );

该语句创建的表包括两列:corp_id和name。其中,corp_id列被设置为表的主键。在第2章中,将会介绍该语句的细节,比如MySQL中所提供的各种数据类型。下面给出的SQL数据语句将向corporation表中插入一行关于Acme Paper Corporation的数据:INSERT INTO corporation (corp_id, name)VALUES (27,’Acme Paper Corporation’);

该语句向corporation表中添加了一行数据,其中corp_id列的值为27,而name列的值是Acme Paper Corporation。

最后,给出一条简单的select语句,以获取刚才创建的数据:mysql> SELECT name   -> FROM corporation   -> WHERE corp_id = 27;+------------------------+| name            |+------------------------+| Acme Paper Corporation |+------------------------+

通过SQL方案语句所创建的所有数据库元素都被存储在一个特殊的表集合,即数据字典中。这些“关于数据库的数据”一般被称为“元数据”,本书第15章将对此进行详细介绍。与用户所创建的表一样,数据字典表也可以通过select语句查询,从而允许在运行时刻查看数据库中的当前数据结构。例如,用户需要编写显示上月新增账户的报表,那么既可以在报表中对account表的各个列名进行硬编码,也可以通过查询数据字典以获取当前的列集合并在每次运行时动态地创建报表。

本书中的大部分篇幅将聚焦于SQL语言中的数据相关部分,包括select、update、insert和delete命令。SQL方案语句将在第2章中说明,并且该章所创建的示例数据库将在全书中使用。一般来说,不需要对SQL方案语句的语法进行太多论述,而对于SQL数据语句,尽管只有寥寥几条,但其中包含了大量值得仔细研究的内容。因此,尽管我尽量介绍更多的SQL方案语句,但本书的大多数章节还是把重点放在SQL数据语句上。1.2.2 SQL:非过程化语句

如果读者有过编程语言的使用经验,可能习惯于定义变量或数据结构、使用条件逻辑(即if-then-else)和循环结构(即do-while-end),并将程序代码分成可复用的小片段(如对象、函数、过程等)。这些代码经过编译后执行,其执行结果精确地(也并不是总是精确)符合编程的预期。无论是使用Java、C#、C、Visual Basic还是其他过程化语言,都可以完全控制程序的行为。提示过程化语言对所期望的结果和产生这些结果的执行机制或过程都进行了定义。非过程化语言同样定义了期望结果,但将产生结果的过程留给外部代理来定义。

使用SQL意味着必须放弃对过程的控制,因为SQL语句只定义必要的输入和输出,而执行语句的方式则交由数据库引擎的一个组件,即优化器(optimizer)处理。优化器的工作包括查看SQL语句并考虑该表的配置信息以及有无索引等,以确定最具效率的执行路径(当然,并不总是最有效率)。大多数数据库引擎允许通过指定优化器选项来影响优化器的决策,比如建议使用特定的索引等。而大多数SQL的用户并不需要考虑这个复杂的层面,而是将之交给数据库管理员或性能调优专家来处理。

因此单独使用SQL并不能开发完整的应用,除了编写简单的脚本来处理某些数据,一般需要将SQL与编程语言相集成。一些数据库厂商已经为用户考虑了这些,如Oracle的PL/SQL语言,MySQL的存储过程语言,以及Microsoft的Transact-SQL语言。在这些语言中,SQL数据语言是其语法的一部分,以准确无误地将数据库查询与过程化命令集成到一起。如果使用非数据库指定的语言,如Java等,则需要使用工具集/API以在代码中执行SQL语句。有些工具集由数据库厂商提供,其他的则由第三方厂商或开源代码提供者所创建。表1-2显示了将SQL集成到特定语言的可用选项。表1-2 SQL集成工具集语言工 具 集JDBC (Java Database Connectivity; JavaSoft)JavaRogue Wave SourcePro DB (third-party tool to connect to Oracle, SQL Server, MySQL, Informix, DB2, Sybase, C++and PostgreSQL databases)Pro*C (Oracle), MySQL C API (open source), and DB2 C/C++Call Level Interface (IBM)ADO.NET (Microsoft)C#PerlPerl DBIPythonPython DBADO.NET (Microsoft)Visual Basic

如果用户仅仅需要执行交互式的命令,那么每种数据库开发商都提供了至少一个简单的命令行工具,用于向数据库引擎提交SQL命令。大多数开发商都提供了图形化的工具,其中包含显示SQL命令的窗口以及另一个显示SQL命令执行结果的窗口。因为本书中的例子都将在MySQL数据库中运行,所以本书使用mysql命令行工具。该工具属于MySQL安装文件的一部分,并用于运行示例和格式化的结果。1.2.3 SQL示例

在本章前面,我说过要演示返回George Blake的checking账户上所有交易的SQL语句,下面就兑现这个承诺,语句和查询结果如下:SELECT t.txn_id, t.txn_type_cd, t.txn_date, t.amountFROM individual i INNER JOIN account a ON i.cust_id = a.cust_id INNER JOIN product p ON p.product_cd = a.product_cd INNER JOIN transaction t ON t.account_id = a.account_idWHERE i.fname = 'George' AND i.lname = 'Blake' AND p.name = 'checking account';+--------+-------------+---------------------+--------+| txn_id | txn_type_cd | txn_date        | amount |+--------+-------------+---------------------+--------+|   11  | DBT      | 2008-01-05 00:00:00 | 100.00 |+--------+-------------+---------------------+--------+1 row in set (0.00 sec)

此处仅对此语句进行简单的分析:该查询查找满足下面两个条件的行,即在individual表中姓名为George Blake的行,以及在product表中的账户名为checking account的行,并通过account表将它们关联起来,然后返回transaction表中所有提交到该账户上的交易信息内容,并分4列显示。如果刚好知道George Blake的客户ID是8并且checking账户的指定代码为“CHK”,就可以简单地根据客户ID找到George Blake在account表中的checking账户,并使用账户ID来查找相关的交易:SELECT t.txn_id, t.txn_type_cd, t.txn_date, t.amountFROM account a INNER JOIN transaction t ON t.account_id = a.account_idWHERE a.cust_id = 8 AND a.product_cd = 'CHK';

在下面的各章节里,将会覆盖到这些查询的所有概念(并且会涉及得很多),但在这里至少需要展示一下它们的大致结构。

前面的查询包含了3个不同的字句,包括select、from和where。几乎所有的查询都至少会包含这3个子句,当然还有其他几个子句可用于更特定的查询目标。下面展示了这3个子句所起的角色:SELECT /* 1个或多个事物*/ ...FROM /* 1个或多个地点*/ ...WHERE /* 1个或多个条件*/ ...提示大多数的SQL实现都将/*和*/标记之间的文本视为注释。

当用户构造查询时,首先需要确定查找的是哪一个或哪些表,并将它们加入from子句中,然后在where子句中增加查询条件以过滤掉并不感兴趣的数据。最后,需要确定从各个表中所应提取的列,并将之增加到select子句中。下面给出一个简单的例子,以展示如何找到所有姓为“Smith”的客户:SELECT cust_id, fnameFROM individualWHERE lname = 'Smith';

该查询搜索individual表,以找到所有lname列匹配字符串'Smith'的行,并返回这些行中的cust_id和fname列。

除了查询数据库,还需要在数据库中建立和修改数据,下面举出一个简单的例子,以说明如何在product表中插入新行:INSERT INTO product (product_cd, name)VALUES ('CD', 'Certificate of Depysit')

糟糕,这里将“Deposit”拼错了,不过没有关系,可以使用update语句来修复这个错误:UPDATE productSET name = 'Certificate of Deposit'WHERE product_cd = 'CD';

注意,与select语句一样,update语句也包含了where子句,这是因为update语句也要识别所需修改的行。在本例中,只需要将要修改的行指定为product_cd列与字符串'CD'相匹配的那些行即可。由于product_cd列是product表的主键,因此可以预计update语句会精确地修改某一行(或零行,如果表中该值不存在)。在任何时刻执行SQL数据语句,都会收到一个来自数据库引擎的反馈,以显示该语句所影响的行数。如果使用交互式工具,比如上文提到的mysql命令行工具,那么可以接收到下面几种操作所影响行数的反馈:● select语句的返回行数;● insert 语句创建的行数;● update语句修改的行数;● delete语句所删除的行数。

可以使用过程化语言,并结合上文提到的工具集来调用SQL语句。工具集通常包含了能够获取SQL数据语句执行信息的调用。一般来说,好的做法应当是检查这个信息以确信语句执行并没有超出预料(比如忘记为delete语句增加where子句,从而删除了表中的所有行)。1.3 什么是MySQL

商业级关系数据库已经存在20多年了,几种最成熟和流行的商业产品包括:● 甲骨文公司的Oracle Database;● Microsoft公司的SQL Server;● IBM公司的DB2 Universal Database;● Sybase公司的Sybase Adaptive Server。

这些数据库服务器的功能十分类似,尽管它们中的一些擅长处理大容量和高流量的数据库,而另一些对于处理对象、大文件或XML文档等更为适合,所有这些服务器都遵从了最新的ANSI SQL标准。这是一件好事,本书将演示如何编写标准的SQL语句,以便无须修改(或极少量的修改)就能够在这些平台中运行。

在最近5年里,除了商业级数据库服务器,开源社区也为创建商业数据库产品的可替代品而努力,其中两个最常用的开源数据库服务器为PostgreSQL和MySQL。MySQL的主页上(http://www.mysql.com)声称其已经拥有超过1000万次的安装,它的服务器版式是免费使用的,并且该服务器软件的下载和安装都非常简单。出于这些理由,本书的所有示例都将在MySQL(6.0版)上运行,并使用mysql命令行工具格式化查询结果。即使你已经使用了另一种数据库且从未打算使用MySQL,本书还是建议安装MySQL服务器的最新版本,并载入书中示例所包含的SQL方案和数据语句。

不过,读者还需要牢记下面的说明:

本书并不是一本MySQL的SQL实现教程。

事实上,本书原意是希望教授如何设计SQL语句并使之无需修改地运行在MySQL上,并能在无需或仅需要极少量修改的情况下,运行在Oracle Database、Sybase Adaptive Server和SQL Server上。

为了使本书中的代码尽量保持数据库平台版本独立性,作者不得不克制对MySQL SQL语言一些有趣特性的介绍,因为这些特性在其他数据库实现上不能被完成。作为补充,附录B覆盖了其中一些特性,以帮助那些准备持续使用MySQL的读者。1.4 内容前瞻

接下来4章的主要目标是简介SQL数据语句,重点放在select语句的3个主要子句上。此外还提供了许多银行业务方面的实例(在下一章中介绍),本书中所有的示例都围绕它们展开。这是因为使用同一个已熟悉的数据库作为例子,将会更容易地掌握问题的核心,而不是每次都需要了解所使用的表。如果读者对总是使用同样的表集合感到厌倦,那么可以在示例数据库中自由增加新表,或者干脆建立自己的试验数据库。

在帮助读者牢固掌握了基础知识后,剩余的章节将会深入讨论更多的概念,它们大多是相互独立的。因此,读者可以根据自己的疑问,自由地向前或向后浏览某个章节。当你完整阅读本书并使用过所有的示例后,你就已经在通往SQL专家的路上迈出了坚实的第一步。

在本章之外,如果读者还需要了解更多关系数据库、计算机数据库系统的历史以及SQL语言方面的知识,可以参考下面列出的一些资源:● C.J. Date’s Database in Depth: Relational Theory for

Practitioners(O’Reilly)● C.J. Date’s An Introduction to Database Systems, Eighth Edition

(Addison-Wesley)● C.J. Date’s The Database Relational Model: A Retrospective

Review and Analysis: A Historical Account and Assessment of E.

F. Codd’s Contribution to the Field of Database Technology

(Addison-Wesley)● http://en.wikipedia.org/wiki/Database_management_system● http://www.mcjones.org/System_R/第2章 创建和使用数据库

本章提供的内容包括如何创建数据库、如何创建表,并且相关的数据将会作为全书的用例。此外还介绍了各种数据类型以及如何在建表时使用它们。因为本书中的示例都运行在MySQL数据库上,因此本章比较偏向使用一些MySQL的特性和记号,但大多数概念对其他数据库服务器也是适合的。2.1 创建MySQL数据库

如果读者已经有了可以使用的MySQL数据库服务器,那么可以跳过下面的安装指南,直接阅读表2-1。不过需要注意,本书使用的MySQL为6.0及以上版本,如果你使用的是以前的版本,就需要将服务器升级或者安装另一个服务器。表2-1 创建示例数据库步 描  述行  为 骤从开始菜单打开运行对话1打开开始菜单并选择运行框2调出命令窗口在对话框中键入cmd并单击确定按钮mysql -u root -p3用root用户登录MySQLcreate database bank;4创建示例数据库grant all privileges on bank.* to 创建用户lrngsql,并赋予5'lrngsql'@'localhost' identified by 'xyz';bank数据库的权限quit;6退出mysql工具包使用lrngsql用户登录mysql -u lrngsql -p;7MySQLuse bank;8关联bank数据库

下面的操作指南显示了在Windows操作系统上安装MySQL 6.0服务器版所需要的最少步骤。

1.访问MySQL数据库服务器的下载页面:http://dev.mysql.com/downloads 。其中所要下载的6.0版本完整的URL为http://dev.mysql.com/downloads/mysql/6.0.html。

2.下载Windows (x86)下的基础压缩包,其中包含了最常用的工具。

3.当弹出“Do you want to run or save this file?”确认窗口后,单击下一步按钮。

4.等待出现MySQL服务器6.0版的安装向导窗口,然后单击下一步按钮。

5.选择典型安装,单击下一步按钮。

6.单击安装按钮。

7.出现MySQL企业版的安装窗口,连续单击两次下一步按钮。

8.当安装完成后,选中Configure the MySQL Server now选项,然后单击完成按钮,以载入配置向导界面。

9.当配置向导界面被载入后,激活标准配置选项按钮,然后同时选中Install as Windows Service和Include Bin Directory in Windows Path复选框,单击下一步按钮。

10.选择修改安全设置复选框,并输入root用户的密码(记住所输入的密码,因为你马上就要用到它!),然后单击下一步按钮。

11.单击执行按钮。

到此,如果一切顺利,MySQL服务器就会被成功安装并运行,否则建议卸载服务并阅读“MySQL在Windows下的安装疑难解答”指南(可以在 http://dev.mysql.com/doc/ refman/6.0/en/windows-troubleshooting.html上找到它)。警告 如果在安装6.0版本之前卸载了旧版本的MySQL,那么可能还需要更进一步清理(比如清除一些旧的注册表条目),以便能够成功获取设置向导。

接下来需要打开Windows命令窗口,调用mysql工具,并创建数据库和用户。表2-1列出了必需的步骤。在第五步中,也可以为lrngsql用户选择与“xyz”不同的密码(但不要忘了所输入的密码哦!)。

现在已经准备好了MySQL服务器、示例数据库以及数据库用户,下面只剩下创建数据库表并产生示例数据的工作了。可以在http://examples.oreilly.com/learningsql/下载相关脚本,并使用mysql工具运行。假设将该脚本文件存放为c:\temp\LearningSQL Example.sql,接下来需要完成以下两项任务:

1.如果已经从mysql工具包中退出,那么需要重复表2-1中的第7和第8步;

2.输入源文件路径c:\temp\LearningSQLExample.sql,并按Enter键。

如此就顺利创建了本书所有例子所使用的数据库,并产生了相关数据。2.2 使用mysql命令行工具

在调用mysql命令行工具时,可以同时指定用户名和所要使用的数据库,如下所示:mysql -u lrngsql -p bank

这可以省去每次启动工具时都要输入use bank命令的麻烦。然后提示需要输入密码,输入完成后会立即出现mysql>标记,在该标记的后面可以运行SQL语句并查看输出结果。例如,需要知道当前日期和时间,可以输入下面的查询:mysql> SELECT now();+---------------------+| now()         |+---------------------+| 2008-02-19 16:48:46 |+---------------------+1 row in set (0.01 sec)

now()是内建的MySQL函数,它返回当前日期与时间。如上所示,mysql命令行工具使用+、-和|等符号将查询结果格式化输出在矩形框中。显示完查询结果(本例的结果只有1行)之后,mysql命令行工具还显示返回的行数,以及SQL语句执行的时间。缺失的子句 某些数据库服务器规定查询语句中必须包含from子句,并在其中至少指明一个表名,比如广泛使用的Orcale数据库。这时如果是仅仅需要调用一个函数,Oracle为此提供了一个特殊的表dual,该表只包含一个名为dummy的列,并且只会有一个数据行。为了与Oracle数据库保持兼容,MySQL也提供了dual表,因此前面的关于当期日期时间的查询可以使用下面的语句:mysql> SELECT now()      FROM dual; +---------------------+| now()         |+---------------------+| 2005-05-06 16:48:46 |+---------------------+1 row in set (0.01 sec)如果没有使用Oracle,并且不需要与之兼容,可以省略dual表,只使用不带from子句的select语句。

使用完mysql命令行语句后,可以简单地输入quit或exit,以返回Windows shell。2.3 MySQL数据类型

一般来说,所有流行的数据库都可以存储同样的数据类型,比如字符串、日期和数字等,但对于一些特殊的数据类型,比如XML文档或大的文本及二进制文档,各种数据库之间存在着较为明显的差异。本书仅针对SQL语言进行介绍,通常用到的数据列98%都是简单数据类型,因此本书只涉及字符型、数值型和日期型。2.3.1 字符型数据

字符型数据可以使用定长或变长的字符串来实现,其不同点在于固定长度的字符串使用空格向右填充,以保证占用同样的字节数;变长字符串不需要向右填充,并且所有字节数可变。当定义一个字符列时,必须指定该列所能存放字符串的最大长度。例如,需要存储最大长度不超过20个字符的字符串,可以使用下面的定义方式:char(20)  /* fixed-length */varchar(20) /* variable-length */

char列可以设置的最大长度为255个字节,而varchar列最多可以存储65535个字节。如果需要存储更长的字符串(比如电子邮件、XML文档等),则需要使用文本类型(mediumtext和longtext),后面将对此进行介绍。一般情况下,使用char类型来存储同样长度的字符串,比如州名的简写,以及使用varchar类型来存储变长字符串。在所有主流数据库中,char和varchar的使用方式都是类似的。提示Oracle数据库对varchar的使用是个特例,使用varchar2类型表示变长字符串列。字符集

对于拉丁系语言,比如英语,包含了一系列字母,其中每个字母只需要1个字节来存储。其他一些语言(如日语和韩语)则包含了大量字符,每个字符的存储需要多个字节,因此这类字符集被称为多字符集。

MySQL可以使用各种字符集来存储数据,包括单字符集和多字符集。可以使用show命令来查看服务器所支持的字符集,如下所示。mysql> SHOW CHARACTER SET;+----------+-----------------------------+--------------------+--------+| Charset  | Description         | Default collation  | Maxlen |+----------+-----------------------------+--------------------+--------+| big5   | Big5 Traditional Chinese | big5_chinese_ci   | 2  || dec8   | DEC West European      | dec8_swedish_ci   | 1  || cp850   | DOS West European      | cp850_general_ci  | 1  || hp8    | HP West European       | hp8_english_ci    | 1 || koi8r  | KOI8-R Relcom Russian     | koi8r_general_ci  | 1 || latin1  | cp1252 West European     | latin1_swedish_ci   | 1 || latin2  | ISO 8859-2 Central European | latin2_general_ci  | 1 || swe7  | 7bit Swedish          | swe7_swedish_ci   | 1 || ascii  | US ASCII            | ascii_general_ci  | 1 || ujis  | EUC-JP Japanese        | ujis_japanese_ci  | 3 || sjis  | Shift-JIS Japanese      | sjis_japanese_ci  | 2 || hebrew  | ISO 8859-8 Hebrew      | hebrew_general_ci  | 1 || tis620  | TIS620 Thai          | tis620_thai_ci    | 1 || euckr  | EUC-KR Korean         | euckr_korean_ci  | 2 || koi8u  | KOI8-U Ukrainian       | koi8u_general_ci  | 1 || gb2312  | GB2312 Simplified Chinese  | gb2312_chinese_ci  | 2 || greek  | ISO 8859-7 Greek       | greek_general_ci  | 1 || cp1250  | Windows Central European  | cp1250_general_ci  | 1 || gbk  | GBK Simplified Chinese   | gbk_chinese_ci   | 2 || latin5  | ISO 8859-9 Turkish     | latin5_turkish_ci  | 1 || armscii8 | ARMSCII-8 Armenian    | armscii8_general_ci | 1 || utf8  | UTF-8 Unicode         | utf8_general_ci   | 3 || ucs2  | UCS-2 Unicode        | ucs2_general_ci   | 2 || cp866  | DOS Russian         | cp866_general_ci   | 1 || keybcs2  | DOS Kamenicky Czech-Slovak | keybcs2_general_ci  | 1 || macce  | Mac Central European    | macce_general_ci   | 1 || macroman | Mac West European     | macroman_general_ci  | 1 || cp852  | DOS Central European    | cp852_general_ci   | 1 || latin7  | ISO 8859-13 Baltic     | latin7_general_ci  | 1 || cp1251  | Windows Cyrillic      | cp1251_general_ci  | 1 || cp1256  | Windows Arabic       | cp1256_general_ci   | 1 || cp1257  | Windows Baltic       | cp1257_general_ci   | 1 || binary  | Binary pseudo charset   | binary         | 1 || geostd8  | GEOSTD8 Georgian     | geostd8_general_ci  | 1 || cp932  | SJIS for Windows Japanese | cp932_japanese_ci   | 2 || eucjpms  | UJIS for Windows Japanese | eucjpms_japanese_ci  |  3 |+---------+----------------------------+-----------------------+----+36 rows in set (0.11 sec)

如果其中的第4列maxlen大于1,那么该字符集为多字符集。

在安装MySQL服务器时,latin1字符集将会被自动选择为默认字符集。当然,还可以为数据库中的每个字符列选择不同的字符集,甚至可以在同一个数据表内存储不同的字符集数据。为数据列指定非默认的字符集,只需要在类型定义后加上系统支持的字符集名称,例如:varchar(20) character set utf8

在MySQL中,还可以改变整个数据库的默认字符集:create database foreign_sales character set utf8;

尽管本书中对字符集的介绍就到此为止了,但实际上关于国际化的主题还包含了更为广泛的内容。如果你需要处理多种非母语的字符集,可以参考Andy Deitsch 和 David Czarnecki’s Java Internationalization 或Richard Gillam的Unicode Demystified: A Practical Programmer’s Guide to the Encoding Standard等著作。文本数据

如果需要存储的数据超过64KB(varchar列所能容许的上限),就需要使用文本类型。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载