《《SQL与关系数据库理论——如何编写健壮的SQL代码》》一导读

简介: SQL无所不在。尽管如此,SQL却难以使用:SQL是复杂的,令人困惑且容易出错(我敢说比它的卫道士所声称的更容易出错)。所以,为了写出你能确信的精确SQL代码(意思是它准确地做到了要求它做的事),你就必须遵从一些适当的准则。


image

前 言

SQL无所不在。尽管如此,SQL却难以使用:SQL是复杂的,令人困惑且容易出错(我敢说比它的卫道士所声称的更容易出错)。所以,为了写出你能确信的精确SQL代码(意思是它准确地做到了要求它做的事),你就必须遵从一些适当的准则。而本书的主题就是:关系化地使用SQL,这就是你需要的准则。不过,这到底意味着什么?难道SQL不是关系化的吗?
没错,SQL确实是用于关系化数据库的标准语言,但是这个事实本身并不能让它成为关系化的语言。让人感到不幸的真相是:SQL在太多的方面背离了关系理论;重复行和null就是两个明显的例子,而它们绝不是仅有的两个问题。结果就是,可以说SQL语言为你提供了“上吊用的绳子”。所以,如果你不想“上吊”,就需要理解关系理论(是什么以及为什么),需要知道SQL对于关系理论的背离之处,还需要知道怎样避免背离之处所造成的这些问题。总的来说,你需要关系化地使用SQL。这样,你就能把SQL当作是真正关系化的语言来运用,而且可以享受使用真正的关系系统所带来的好处。
如果每个人都已经关系化地使用SQL了,就不再需要像本书这样的书籍了。但问题是,情况并非如此。我看到当前的SQL使用中存在着大量的糟糕实践,甚至看到有的(本应具有更好认知的)作者在课本或类似出版物中推荐这些糟糕实践。事实上,对此方面文献的回顾是相当令人沮丧的。关系模型诞生于1969年,然而直到40多年后的今天,它似乎还是没有被数据库领域中的大多数人所充分理解。所以,本书将关系模型本身作为一个组织原则,其部分原因也来自于此。本书深入讲解关系模型的诸多特性,并说明在每种情况下为了遵守这些特性怎样最好地使用SQL。
预备知识
我假设你是熟悉SQL的数据库专业技术人员。具体地说,我假设你具有对于SQL标准(或至少是对于一个SQL产品)的工作知识。然而,我并不假设你深入理解关系理论(尽管我确实希望你明白:关系模型是个好东西,并且只要可能就应坚持关系模型)。所以,我会详细描述关系模型的各个特性以免误解。我还会说明怎样使用SQL去遵守那些特性。不过,我不会证明所有特性;相反,我假设你在数据库方面已经具有足够的经验,能够理解为什么键的概念是有意义的,为什么有时需要做连接,而又为什么需要支持多对多联系,等等。(如果要包括这些证明,那么本书就会大变样,比现在的厚得多。况且,那样的书已经有了。)
我说过,我期望你熟悉SQL。虽然如此,我还是会详细“解释SQL的某些方面,尤其是实践中不常碰到的那些内容。比如,SQL的“可能非确定性表达式”(possibly nondeterministic expression)。参见第12章。
深入数据库
本书基于并要超越以前的《Database in Depth: Relational Theory for Practitioners》(O'Reilly Media Inc.,2005)一书。在那本书中,我的目标如下(摘自前言):
在数据库圈子里工作多年之后,我终于意识到:需要有一本书,用一种未被现存产品、商业实践或SQL标准的怪癖所污染的方式为专业人员(而不是新手)解释关系理论的基本原理。我写这本书就是为了满足这个需要。我所期望的读者是有经验的数据库专业人员:他们足够诚实,勇于承认自己并不理解自身领域所基于的以及自己应该知道的那个理论。“那个理论”所指的当然就是关系模型,尽管该理论的基本思想都非常简单,但这些思想还是被广泛地误传误评。事实上,它们似乎就没被真正理解过。比如,下面就有一些关系模型的问题,你能回答出多少?注1

  1. 第一范式到底是什么?
  2. 关系和谓词之间的联系是什么?
  3. 语义优化是什么?
  4. 映像关系是什么?
  5. 为什么半差(semidifference)重要?
  6. 为什么延迟完整性检查毫无意义?
  7. 关系变量是什么?
  8. 前束范式是什么?
  9. 关系能有一个其取值为关系的属性吗?
  10. SQL是关系完备的吗?
  11. 为什么“信息原理”重要?
  12. XML怎样才符合关系模型?
    本书对这些问题以及相关问题进行了解答。总的来说,本书就是为了帮助数据库专业人员去深入理解关系理论,并在日常的专业工作中很好地运用这些对于关系理论的深入认知。

正如这段引文的最后一句所言,我曾经希望本书读者不需要进一步的协助就能够自己运用关系理论的思想。不过,我随后就意识到:与流行观点恰恰相反,要在不违反关系理论原理的情况下使用SQL这种语言可绝不是一眼就能看出来的事。所以,我决定将先前的书进行扩展,以便包括对于该问题(我指的是怎样关系化地使用SQL)明确具体的建议。本书的目标仍然和先前的书一致:帮助数据库专业人员深入理解关系理论并在其日常的专业工作中很好地运用这些对于关系理论的深入认知。不过,我试着让书中的内容更好消化一些,更容易应用。总之,我收录了大量与SQL相关的资料(也正因为如此,本书才会比先前的那本书在篇幅上有所增加)。
对正文的进一步说明
我需要进一步说明几点。第一,我对于关系模型的理解在多年来是不断演进的,并且还将继续下去。本书代表了我对该主题的最新思考,所以,如果你发现这本书和我的其他书(尤其是本书所要超越的那本书)之间存在什么技术上的差异(确实有几个),请以这本书为准。不过,绝大部分的差异都是相当微小的,而且,我在必要的时刻总会将新的术语及概念和先前的术语及概念联系起来。
第二,我会讲到理论,不过,我的信条是:理论是实用的。之所以我要明确指出此点,是因为有太多的人不这么认为,即很多人认为理论化的东西是不实用的。但真相是:理论真的是绝对、非常实用的。关系理论的目的不是理论本身,而是让我们能够构建完全实用的系统。关系理论中的每个细节都缘自于切实的实用原因。正如Stéphane Faroult(先前那本书的评审者)所写:“一旦你有了一点实践,你就会意识到不懂得关系理论是不行的。”而且,关系理论不仅是实用的,而且是基础的、直截了当的、简单的、有用的,(正如我希望在本书中证明的那样)也会是有趣的。
当然,对于前述论题,我们就不必去找比关系模型本身还要更进一步的例证了。实际上,在我们这样的环境下(即建立在一个伟大的理论思想之上的几十亿美元规模的产业)真的应该不必为“理论是实用的”辩解。不过,我猜某些人的观点会是“没错,但理论为我做了什么呢?”总之,坚信理论是重要的人们必须不断地向批评者证明自己,这又是一个我认为需要本书的原因。
第三,前面提到过,本书会讨论相当多的SQL相关特性细节或关系模型细节。(对于和关系化不太相关的主题,本书有意进行了回避。比如,本书中关于事务的内容就不多。)自始至终,我都设法说清楚适用于SQL的讨论以及适用于关系模型的讨论。不过,我想强调的是:我并不想对SQL进行详尽全面的讨论。SQL太复杂了(更何况还为做同一个事情提供了太多的不同方法,而且还有那么多例外和特例),要想详尽全面地讨论它(我都怀疑是不是真的能做到这点)只会适得其反;而且,详尽全面的讨论肯定会增加本书的篇幅。所以,我设法只关注我所认为的最重要问题,而且尽可能简短地说明所选择的问题。我想说,如果你做了我告诉你的每件事,并且不做我没有告诉你的任何事,那么你基本上就会是安全的:你就是关系化地使用了SQL。不过,我的说法到底有没有道理,或者在多大程度上是有道理的必须由你来判断。
对于前文我还要补充说明的是:很遗憾,有些情况下就是不能关系化地使用SQL。比如,虽然关系模型将延迟完整性检查作为逻辑错误明确拒绝,但有的SQL完整性检查必须延迟(通常延迟到提交时刻)。尽管本书对在这种情况下如何进行处理给出了建议,但是我担心最终还是会“尽你的能力做好”。至少,我希望你会理解背离关系模型所带来的风险。
我还要说的是,本书所给的一些建议也不是特定于关系化的,而只是关于一般的优秀实践的——尽管有时会受(不太明显的)关系化方面的影响。避免型转就是这种情况的很好示例。
第四,请记住,除非明确声明,我在全书中使用的都是标准版本的SQL语言(而不是某些专属的方言)。尤其是,我和SQL标准一样假设其发音为“ess cue ell”而不是“sequel”(尽管后者在业界很普遍)。
第五,除非提示,否则本书是要按顺序阅读的(大多数章节都在某种程度上依赖于前面章节的内容,所以你不应该跳来跳去)。还有,每一章都有一套练习题。当然,不是必须做这些练习,但是我觉得试试某些练习总不是坏事。练习的答案(经常给出相应主题的更多信息)在附录F中给出。
第六,我有一些基于本书内容的研讨会记录可以使用,其详细内容参见www.justsql.co.uk/chris_date/chris_date.htm或www.thethirdmanifesto.com。其中一个研讨会的在线版本也是可用的,地址是http://oreilly.com/catalog/0636920010005/
使用代码示例
本书旨在帮助你完成手头的工作。一般而言,你可以在自己的程序和文档中随意使用本书中的代码。除非原样引用大量的代码,否则你无须征得我们的许可。例如,在编写程序时引用了本书的若干代码片段是无须许可的。而销售或发行O扲eilly图书的示例光盘则须要许可。通过引用书中内容及示例代码的方式答疑解难无须许可,而将书中的大量示例代码加入到你的产品文档中则须要许可。
如果你在引用时注明出处(并非必须),我们将不胜感激。引用通常包含书名、作者、出版商及ISBN。例如:“SQL and Relational Theory, Second Edition, by C.J. Date (O扲eilly). Copyright 2012 C.J. Date,9781449316402”。
如果你发现自己对示例代码的使用有失公允或违反了上述条款,敬请通过permissions@oreilly.com与我们取得联系。
评论及疑问
如果你想就本书发表评论或有任何疑问,敬请联系出版社:
美国:
O扲eilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
中国:
北京市西城区西直门南大街2号成铭大厦C座807室(100035)
奥莱利技术咨询(北京)有限公司
我们为本书制作了网页,列出了勘误表、示例以及任何附加信息。你可以通过http://shop.oreilly.com/product/0636920022879.do访问该网页。
如果你想就本书发表评论或提问技术问题,请发送E-mail至:bookquestions@oreilly.com。
关于我们的书籍、课程、会议以及新闻的更多信息,敬请访问我们的网站http://www.oreilly.com
在Facebook上找到我们:http://facebook.com/oreilly.
在Twiiter上关注我们:http://twitter.com/oreillymedia.
在YouTube上观看我们的视频:http://www.youtube.com/oreillymedia.
致谢
我一直都想着修订先前那本书以便包括关于SQL的更多内容,然而直到2007年后期的一次针对数据库专业人员的授课时才下定决心。那次授课由Toon Koppelaars讲课,并且课程基于他和Lex de Haan所写的书籍(参见本书附录G),课程进行得也很好。然而,那次授课给我的最大冲击就是亲眼看到参与人员在将关系原理及逻辑原理应用于对于SQL的使用过程中时所面对的各种困难。现在,我猜那些参与人员已经具有了那些主题的一些知识,毕竟他们是数据库专业人员。但是我觉得他们在将关系化思想和逻辑思想运用于日常数据库工作方面确实需要一些指导。所以,我编写了这本书。因此,首先我要感谢Toon和Lex为我启动这个项目提供了必要的动力。我还要感谢对于早期草稿给出评议的评审者Herb Edelstein、Sheeri Ktitzer、Andy Oram、Peter Robson和Baron Schwartz以及给予其他技术协助的Hugh Darwen和Jim Melton。其次,我要一如既往地感谢我的妻子Lindy,感谢她多年来一直支持着我所有的数据库项目。最后,我要感谢所有在O扲eilly工作的同仁,特别是Isabel Kunkle和Andy Oram,感谢他们对于本书出版的鼓励、贡献和支持。

目 录

第1章 做好准备
1.1 关系模型被严重地误解了
1.2 关于术语的一些说明
1.3 原理而非产品
1.4 原始模型回顾
1.5 模型vs.实现
1.6 关系的性质
1.7 基关系vs.导出关系
1.8 关系vs.关系变量
1.9 值vs.变量
1.10 小结
1.11 练习题
第2章 类型和域
2.1 类型和关系
2.2 相等性比较
2.3 数据值原子性
2.4 类型是什么
2.5 标量类型vs.非标量类型
2.6 SQL中的标量类型
2.7 SQL中的类型检查和型转
2.8 SQL中的字符序
2.9 SQL中的行类型和表类型
2.10 小结
第3章 元组、关系、行、表
3.1 元组是什么
3.2 SQL中的行
3.3 关系是什么
3.4 关系及其主体
3.5 关系是n维的
3.6 关系比较
3.7 TABLE_DUM和TABLE_DEE
3.8 teSQL中的表xt
3.9 SQL中的列命名
3.10 小结
第4章 不要重复,不要null
4.1 重复有什么问题
4.2 重复:深入讨论
4.3 在SQL中避免重复
4.4 null有什么毛病
4.5 在SQL中避免null
4.6 对外连接的说明
4.7 小结
4.8 练习题
第5章 基关系变量和基表
5.1 更新是集合级别的
5.2 关系赋值
5.3 关于候选键的更多内容
5.4 关于外键的更多内容
5.5 关系变量和谓词
5.6 关系 vs. 类型
5.7 练习题
第6章 SQL和关系代数I:原始运算符
6.1 一些预备知识
6.2 关于闭包的更多内容
6.3 限制
6.4 投影
6.5 连接
6.6 并、交和差
6.7 哪些运算符是基本运算符
6.8 逐步形成表达式
6.9 关系表达式到底表示什么
6.10 计算SQL表表达式
6.11 表达式变换
6.12 属性名依赖
6.13 练习题
第7章 SQL和关系代数II:附加运算符
7.1 排他并
7.2 半连接和半差
7.3 扩展
7.4 映像关系
7.5 除
7.6 聚集运算符
7.7 再议映像关系
7.8 汇总
7.9 再议汇总
7.10 分组、去分组和关系值属性
7.11“WHAT IF”查询
7.12 对于递归的说明
7.13 ORDER BY是怎么回事
7.13 练习题
第8章 SQL与约束
8.1 类型约束
8.2 SQL中的类型约束
8.3 数据库约束
8.4 SQL中的数据库约束
8.5 事务
8.6 数据库约束为什么必须立即检查
8.7 不是有些检查必须延迟进行吗
8.8 约束与谓词
8.9 各种问题
8.10 练习题
第9章 SQL与视图
9.1 视图是关系变量
9.2 视图和谓词
9.3 检索运算
9.4 视图和约束
9.5 更新运算
9.6 视图的作用
9.7 视图和快照
9.8 练习题
第10章 SQL与逻辑
10.1 为什么需要逻辑
10.2 简单命题和复合命题
10.3 简单谓词和复合谓词
10.4 量词化
10.5 关系演算
10.6 关于量词化的更多内容
10.7 一些等价关系
10.8 小结
10.9 练习题
第11章 使用逻辑表述SQL表达式
11.1 一些变换法则
11.2 例1:逻辑蕴涵
11.3 例2:全称量词化
11.4 例3:蕴涵和全称量词化
11.5 例4:相关子查询
11.6 例5:命名子表达式
11.7 例6:关于命名子表达式的更多内容
11.8 例7:处理模糊性
11.9 例8:使用COUNT
11.10 例9:连接查询
11.11 例10:唯一量词化
11.12 例11:ALL或ANY比较
11.13 例12:GROUP BY和HAVING
11.14 练习题
第12章 关于SQL的其他主题
12.1 SELECT *
12.2 显式表
12.3 名称限定
12.4 区间变元
12.5 子查询
12.6 “可能非确定性”表达式
12.7 空集合
12.8 简化的BNF语法
12.9 练习题
附录A 关系模型
附录B SQL背离关系模型之处
附录C 处理信息丢失的关系方法
附录D Tutorial D语法
附录E 本书建议汇总
附录F 练习答案
附录G 深入阅读建议

相关文章
|
1月前
|
SQL 人工智能 算法
【SQL server】玩转SQL server数据库:第二章 关系数据库
【SQL server】玩转SQL server数据库:第二章 关系数据库
66 10
|
1月前
|
SQL 算法 数据库
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
103 6
|
2月前
|
SQL XML Java
整理几个常用的sql和其他代码
整理几个常用的sql和其他代码
13 1
|
2月前
|
SQL 存储 关系型数据库
【MySQL】——关系数据库标准语言SQL(大纲)
【MySQL】——关系数据库标准语言SQL(大纲)
60 0
【MySQL】——关系数据库标准语言SQL(大纲)
|
3月前
|
SQL Java 关系型数据库
Flink SQL 问题之用代码执行报错如何解决
Flink SQL报错通常指在使用Apache Flink的SQL接口执行数据处理任务时遇到的问题;本合集将收集常见的Flink SQL报错情况及其解决方法,帮助用户迅速恢复数据处理流程。
155 6
|
3月前
|
SQL 关系型数据库 MySQL
MySQL日期函数的SQL代码示例和使用场景
MySQL日期函数的SQL代码示例和使用场景
29 0
|
1天前
|
SQL 存储 数据库连接
LabVIEW与SQL Server 2919 Express通讯
LabVIEW与SQL Server 2919 Express通讯
|
2天前
|
SQL Windows
安装SQL Server 2005时出现对性能监视器计数器注册表值执行系统配置检查失败的解决办法...
安装SQL Server 2005时出现对性能监视器计数器注册表值执行系统配置检查失败的解决办法...
12 4