你不可不知的关系数据库理论

978-7-115-37921-4
作者: 【美】C.J.Date
译者: 张大华方帅
编辑: 傅道坤

图书目录:

详情

本书介绍了计算机领域中的关系理论,并通过这些理论来讲解SQL语言,并特别展现了这一理论如何帮助用户解决正确和高效地使用SQL的实际问题。C.J. Date是数据库领域的一位重量级人物,本书的重点并不是理论本身,而是通过掌握理论来解决实际问题。

图书摘要

版权信息

书名:你不可不知的关系数据库理论

ISBN:978-7-115-37921-4

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

• 著    [美] C. J. Date

  译    张大华 方 帅

  责任编辑 傅道坤

• 人民邮电出版社出版发行  北京市丰台区成寿寺路11号

  邮编 100164  电子邮件 315@ptpress.com.cn

  网址 http://www.ptpress.com.cn

• 读者服务热线:(010)81055410

  反盗版热线:(010)81055315


Copyright © 2013 by O’Reilly Media.Inc.

Simplified Chinese Edition, jointly published by O’Reilly Media, Inc. and Posts & Telecom Press, 2015. Authorized translation of the English edition, 2013 O’Reilly Media, Inc., the owner of all rights to publish and sell the same.

All rights reserved including the rights of reproduction in whole or in part in any form.

本书中文简体字版由O’Reilly Media, Inc.授权人民邮电出版社出版。未经出版者书面许可,对本书的任何部分不得以任何方式复制或抄袭。

版权所有,侵权必究。


关系型数据库是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。关系型数据库的基础——关系理论被认为是 SQL的基础。

本书为我们讲解了什么才是真正的关系型数据库,与当前的数据库产品相比,它的特点和优势是什么。本书分为3部分,共计14章。第一部分是数据库的基础,讲解了数据库基本概念,关系和关系变量,码、外码和相关概念,关系运算符,约束和断言,关系模型等内容;第二部分讲解了事务的相关概念,以及如何设计一个好的数据库;第三部分则讲解了SQL相关的知识,其内容涵盖了SQL基本表,SQL操作符和运算符,SQL约束,SQL 与关系模型等内容。本书最后的 5 个附录涵盖了Tutorial D语法、TABLE_DUM和TABLE_DEE、集合论、关系演算,以及与关系理论知识相关的资源。

本书适合数据库开发、维护人员以及高校数据库专业的师生阅读。对于想要真正理解什么是关系型系统的读者来说,本书也是不错的选择。


O’Reilly Media通过图书、杂志、在线服务、调查研究和会议等方式传播创新知识。自1978年开始,O’Reilly一直都是前沿发展的见证者和推动者。超级极客们正在开创着未来,而我们关注真正重要的技术趋势——通过放大那些“细微的信号”来刺激社会对新科技的应用。作为技术社区中活跃的参与者,O’Reilly的发展充满了对创新的倡导、创造和发扬光大。

O’Reilly为软件开发人员带来革命性的“动物书”;创建第一个商业网站(GNN);组织了影响深远的开放源代码峰会,以至于开源软件运动以此命名;创立了《Make》杂志,从而成为DIY革命的主要先锋;公司一如既往地通过多种形式缔结信息与人的纽带。O’Reilly的会议和峰会集聚了众多超级极客和高瞻远瞩的商业领袖,共同描绘出开创新产业的革命性思想。作为技术人士获取信息的选择,O’Reilly现在还将先锋专家的知识传递给普通的计算机用户。无论是通过书籍出版、在线服务或者面授课程,每一项O’Reilly的产品都反映了公司不可动摇的理念——信息是激发创新的力量。

“O’Reilly Radar博客有口皆碑。”

      ——Wired

“O’Reilly凭借一系列(真希望当初我也想到了)非凡想法建立了数百万美元的业务。”

      ——Business 2.0

“O’Reilly Conference是聚集关键思想领袖的绝对典范。”

      ——CRN

“一本O’Reilly的书就代表一个有用、有前途、需要学习的主题。”

      ——Irish Times

“Tim是位特立独行的商人,他不光放眼于最长远、最广阔的视野并且切实地按照Yogi Berra的建议去做了:‘如果你在路上遇到岔路口,走小路(岔路)。’回顾过去Tim似乎每一次都选择了小路,而且有几次都是一闪即逝的机会,尽管大路也不错。”

——Linux Journal


目前,现有大量新型数据库技术得到了快速发展并受到大量关注,无论是已有进展的“云计算”产业,还是流行的关注点“大数据”,其核心都是对“数据”的研究,这就使得数据库中的关系理论和SQL得到更进一步的丰富和发展。市面上关于SQL语言或者关系理论或者二者兼而有之的书籍参差不齐,良莠混杂,很难有一本能循序渐进深入讲解该领域的书籍。本书译者结合自己多年工作经验,结合实际行业内需求,挑选C. J. Date的这本图书供读者参考。

C. J. Date是最早认识到Code在关系模型方面所做的开创性贡献的学者之一,他是关系数据库技术领域中非常著名的独立撰稿人、学者和顾问,他使得关系模型的概念普及化。他参与了IBM公司的SQL/DS和DB2两大产品的技术规划和设计。30多年来,Date一直活跃在数据库领域中,他的著作包括:《SQL和关系理论(第二版)》、《数据库设计和关系理论》、《视图修改和关系理论》、《数据库系统导论》、《对象关系数据库基础:第三次宣言》等。

本书共分为14个章节,内容分别为关系型数据库“基础介绍”、“事务和数据库设计”、“SQL”及附录四个部分,翻译团队由中国电力科学研究院信息通信研究所相关人员组成。具体分工为:前言、译者序、“基础介绍”部分由张大华、方帅负责;“事务和数据库设计”由张大华、方帅、纪鑫、李哲、陈相舟负责;“SQL”部分由谢迎军、丁辉、常亮、刁倩、刘月林、钱声攀、魏俊负责;附录部分由上述全体翻译团队共同负责;全书译文审核与校正由北京航空航天大学柳永坡、张奎完成。

本书中文版能够出版发行,首先要感谢本书的作者,是他们为我们著作了一本好书。其次要感谢人民邮电出版社引进了本书,使我们获得了翻译此书的机会,并实现将其介绍给国内广大读者的良好愿望。也借此机会向本书的技术审校人员致以崇高的敬意,他们使本书的质量与水平向前迈进了一大步。此外,特别要感谢国家电网公司高级顾问曾楠,他以巨大的热情和高度的责任心在本书翻译过程中给予了大力的技术指导工作。也要感谢幕后的工作人员,是他们的辛勤劳动使得本书顺利付梓。在此,译者代表对所有为此书的出版做出贡献的人表示深深的感谢和崇高的敬意!

本书对原著的错误之处作了一些修正,在原著难懂或需要提醒的地方添加了一些译者说明。尽管我们在翻译过程中力图做得更好,但终究因业务水平、英文水平,乃至中文文学水平的欠缺,以及翻译过程中的粗心和不够严谨,致使本译作存在错误、不足和不当之处,也恳请读者批评指正,并热切期望读者对本书提出宝贵意见和建议。

译者

2014年12月


谨将本书献给我的妻子Lindy和女儿Sarah、Jennie。我爱你们。


C. J. Date是一位独立作家、演说家、研究员、顾问,在关系数据库技术领域颇有建树。C. J. Date以他的An Introduction to Database Systems(第8版,Addison-Wesley,2004年出版)一书而闻名,到写作本书时为止,该书发行量已达到近90万册,被全球数百所大学和学院使用。他还出版了许多数据库管理方面的著作,新近出版的包括下面这些著作。

Date先生于2004年成为计算机工业名人堂中的一员。他在用明晰易懂的方式解释复杂技术课题方面具有傲视群雄的能力。


关系数据模型是百年来最伟大的技术发明之一,它是我们完成数据库领域任何事情的基础。的确,它使数据库管理成为一门科学,而不再像过去那样是一些技巧、技术和经验法则的特定集合。因此,每一个与数据库管理有关的专业人员,或多或少都会主动去获得一些与关系模型有关的知识,以加深对关系模型的理解。因为如果没有它,想开展高效的工作、获得较高的工作性能几乎是不可能的。

不幸的是,想要达到如上所说的“获得知识,加深理解”是不容易的。这有多方面的原因,但影响最大的原因是SQL语言,它是一种“关系型”语言的官方标准[1],当今市场上的每个数据库产品都支持其中的某些方面。大家普遍承认,至少是应该普遍承认,作为关系模型的抽象概念的某种具体实现,SQL 有着非常严重的缺陷(这是我在前面那句话中给“关系型”加上引号的原因)。至于在数据库世界,每个人之所以都知道一些关于SQL的知识,是几乎所有的关系型(或可能的关系型)教学的重点都倾向于SQL本身,而不是基本的理论。因此,仅仅因为他们知道 SQL,人们就认为他们知道关系理论,也就不足为奇了。然而,令人难过的是,如果你只是像这样知道 SQL,那么你肯定不知道关系理论,而你不知道的事情最终可能会伤害你。

本书的首要目的就是详细地教你关系理论(至少是尽我所能地详细),第二个目的是从关系理论的角度描述SQL(或者描述SQL的核心特征),这也可能会给我带来一些其他灵感。一些读者可能知道,不久前我出版了另一本书来论述这件事情,书名为SQL and Relational Theory: How to Write Accurate SQL Code(第2版,2012年O’Reilly出版)。然而,与现在的这本书不同,早期的图书主要是面向数据库从业人员,通常情况下适用于至少有三四年的“工作在数据库系统第一线”的人员,或者经常把它作为日常工作一部分的人员(因此,肯定会有一些关于SQL的工作经验)。那本书的主要目的是展示如何把关系理论应用到使用SQL的过程中,因此,SQL的行为看起来就像是一个真正的关系语言一样(在那本书中我引用的一个规则是,从关系型的角度使用SQL)。在本书和那本书之间不可避免地会有一些重复。实际上,本书中有一些文字就是从早期写作的图书中复制和粘贴的,有些几乎是完全一样。不管怎样,你现在看到的一定是一本不同的图书,因为它是面向不同的读者(参看下面的详细解释)。然而,本书接下来的内容还需要频繁引用早期的图书,所有的引用都以简写的形式给出(即SQL and Relational Theory)。而且,我认为如果你熟悉我的早期作品,那么你从本书中可能不会获得太多的知识。当然,我不是不鼓励你阅读此书,只是如果你读了,你可能不会发现太多的新知识。

本书面向的读者是计算机专业人员。前提是你了解一些通用的计算机和编程知识,也至少熟悉一种通用的编程语言。但是你不需要了解数据库,无论是关系型的还是其他的,也不用了解SQL。当然,你至少要知道当今的数据库系统都几乎被假设为“关系型”(不管它是不是),但是我不会依赖于这个假设。然而,请注意,如果你恰好已经了解数据库的一些知识,那么你或许要格外留心本书中讲的内容!你可能会发现需要抛掉一些以前的想法(我们大家都知道,抛掉已有的想法是很难的)。当今的数据库产品即便被贴上了“关系型”的标签,但实际上却不完全是关系型的,它们在很多方面都与理论上的关系型思想相差很远,你很快就会发现这一点。正如我在SQL and Relational Theory一书中写到的那样:

在这里我要为我带有进攻性的口吻道歉。但是如果你对关系模型的了解仅仅来自于对SQL的了解,那么恐怕你并没有如你所期待的那样真正了解关系模型,你也许应该知道“有些事情不是这样的”。我也不能过于强调:SQL和关系模型不是一回事。

注意:我想说的是,关于本书的详细材料可以参照我的一个在线论坛,如果想要更详细的资料,请登录网站,网址为:www.justsql.co.uk/chris_date/chris_date.htm,也可以参考视频,网址为:http://oreilly.com/go/date

本书分为三个部分及附录。第一部分为“基础知识”,主要介绍了关系模型本身,换句话说,介绍了关系数据库技术的理论基础(虽然它也强调了整个理论的实际应用)。第二部分为“事务和数据库设计”,主要讨论了为了理解通用的数据库和特定的关系型数据库而需要的知识,但是不需要真正了解关系模型本身(除非它以该模型作为基础)。第三部分为“SQL”,又回到了第一部分的材料,展示了该部分讨论的概念是如何用SQL语言实现的。至于附录,是很多材料的混合(这也是附录通常的作用),我认为这不值得在书的正文部分过多描述,因此都放在了这里加以详细描述。

注意:复习题和练习是大部分章节中不可或缺的一部分,我建议你在查阅后面的答案之前尝试着回答这些问题,以使自己得到训练。尤其你要知道的是,经常有目的地做些练习,可以在很多方面得到锻炼。

我想再一次感谢我的妻子Lindy,她在本书的整个著作过程中给予了大力支持,同时要感谢所有的前辈。我还要感谢David Livingstone,是他最初给了我写本书的一些建议或类似的想法,也要感谢Allen Noren,是他促使我写作本书的(在我的其他的由O’Reilly出版的著作中,Allen的想法为此奠定了坚实的基础,就像本书一样,也是奠定了理论基础。我相信他是对的,这就是我想要写的著作)。最后,我还要感谢在线论坛的讨论者,因为人物众多,不胜枚举,他们的问题和评论帮助我合理地组织了本书的结构,也帮助我决定了本书内容的取舍。当然,无论是事实还是判断中的任何错误,我都会一如既往地负责。

C. J. Date

加利福尼亚希尔兹堡

2013年

[1] 多年来,SQL已经演变了几个版本。在本书出版时的版本是2011版(即SQL:2011)。规范的引用格式为:国际化标准组织(ISO),数据库语言SQL,文档ISO/TEC9075:2011。第10章和附录E对这种引用做了详细的介绍,第10章还专门简要介绍了它的相应发展史。



我们的生活被琐事浪费掉了……简化,简化。

——Henry David Thoreau: Walden(1854)

本章是一个介绍性的概述,目的是提供一个距离我们非常遥远的观点。它故意没有讲解得很深奥,如果你已经了解了关于数据库管理的一些知识,也许会发现本章内容都已熟悉。但是我想你应该花些时间把本章从头到尾通读一遍,这是非常值得的,如果只是想获得背景知识,可以看后续的章节。同时,本章还介绍了一些可以运行的示例,在后面的章节中我们也一定会遇到这些例子,并逐步熟悉。

数据库被认为是一种电子文件柜,它包含了一些数字化的信息(即数据),这些信息可以被永久保存在某种存储介质上,通常是被保存在磁盘上。用户可以通过管理数据库的软件发出请求(request)或命令(command)来向数据库中插入信息,删除、修改或检索数据库中已经存在的信息,这种管理数据库的软件叫做数据库管理系统(DBMS)。

注意:

 

在本书中,术语user的含义将根据上下文的要求理解为应用程序员或者是交互用户[1]或者是应用程序员和交互用户。

实际上,现在这些发给DBMS的用户请求可以采用各种各样的方法进行格式化(例如,单击鼠标)。然而,为了达到我们的目的,采用某种正规语言中的简单文本串的形式来表示这些请求会更方便些。例如,有一个人力资源数据库,我们可能会这样写:

EMP WHERE JOB = 'Programmer'

这个表达式表示了一个检索请求(retrieval request)——但通常我们都称之为查询(query)——这个表达式的含义是要获得员工工作性质为Programmer的员工信息。

图1.1给出了某种类型数据库中的一些样本数据,包含供应商表(suppliers)、零件表(parts)、货物表(shipments,即由供应商提供的零件数量)。

图1.1 供应商表和零件表数据库——样本数据

从图1.1可以看出,这个数据库包含了三个文件(file)或称之为(table)。(实际上它们就是关系’[relations],我们将在第2章讲解,但在本章中我们称之为“文件”或者“表”。)这些表的名称分别为S、P和SP。因为它们都是表,所以它们都是由行和列组成的(在传统的文件术语中,行对应为文件中的记录,列对应为字段)。可以按照如下的方式来理解。

本书中其他地方的例子大多是基于前面提到的这个数据库。现在,你可以再仔细看看前面的这个数据库,我已经在很多其他的书籍和著作中用过,包括SQL and Relational Theory[2],在许多现场演讲时也用过,所以你可能会有点厌烦的感觉。但是就像我在别处写的那样,我相信在各种不同的出版物中使用相同的一个例子对学习是有帮助的,而不是障碍。当然,真正的数据库应该比这个像“玩具”一样的例子复杂得多,但是使用接近于实际的例子会遇到的麻烦就是它们太复杂了,在某种程度上会造成只见树木不见森林的结果。所以我还是要说,即使这个例子有点不现实,但供应商和零件表数据库至少适合说明我们后面要测试的所有观点。因而,要达到本书的目的,这个例子足够了。但要注意的是,在本书其余部分的例子中,除非做特殊说明,否则我会假定使用图1.1所示的特定的样本数据。

从现在开始,每当我提到“给出一个典型的数据库”,如图1.1所示,意味着给出一个如用户想象的那样的数据库(有时称之为逻辑数据库[logical database])。逻辑数据库与物理数据库是相对而言的,物理数据库是被数据库管理系统(DBMS,Database Management System)所理解的(即它是实际存储在计算机中的数据)。因此,需要进一步强调的是,这里所谓的逻辑和物理数据库并不是两个完全不同的事情,相反,它们是从不同视角来看待的同一事情,如图1.2所示。

图1.2 数据库系统结构

从图1.2可以看出,DBMS(即管理数据库的软件)作为系统逻辑层和物理层之间的一个媒介,可以有效地提供以下服务:用户向数据库发出请求的格式可以依据逻辑数据库的形式来标识,然后依据对应的物理数据库,DBMS会一一实现这些请求。

DBMS提供的一个通用功能就是向用户隐藏系统物理级别的实现细节(大多数的程序设计语言也是在物理级别向用户隐藏实现细节),换句话说,DBMS给用户提供了一个更抽象的数据库概念,相比物理数据库级别而言,这种方式会更友好。例如:以实际存储在系统中的方式来表示数据库概念[3]

现在我们知道了DBMS是一个复杂的软件,它包含很多构件。但是有一个构件我现在必须提一下,因为它是这本书的主题,它就是优化器(optimizer)。优化器是DBMS的构件之一,其主要职责是决定如何正确执行用户的请求。大多数请求(实际上几乎是所有的请求)都能够通过各种不同的方法来实现。而且,这些不同的方法一般在性能特点上有很大区别。特别是在执行时间上它们确实有很大区别,可以从几微秒到几天。因而,对于优化器来说,选择一个“好”方法去实现特定的请求是非常重要的,这里的“好”实际上是指好的性能(good performance)。

前文中存在一个直接而且重要的暗示就是假设优化器能很好地发挥它的作用,用户根本不必考虑性能的问题。但有一个事实我必须在这里声明一下(这是突然在我脑海中闪现的一个想法),记录一直是关系模型中的一个主要目标,性能问题应该是系统所担忧的,而不是用户应该关心的。从某种程度上来说,如果这个目标没有达到,就说明系统是失败的(或者确切地说,至少是不成功的)。

逻辑数据库和物理数据库是有区别的,要严格进行区分,但这个事实也允许我们实现一个重要的目标,就是数据独立性(data independence)。数据独立性(顺便说一下,这其实不是一个很恰当的数据,但似乎我们也只能坚持使用它)意味着我们可以随意改变数据在系统中的存储和访问方式,而对于用户看到的数据库却不需要做任何相应的变化。其实我们可能想改变数据库存储或访问方式的原因就是性能(performance)。我们做这样的改变而不用去修改用户看到的数据库,这意味着已存在的一些应用程序、查询等都可以在变化之后仍然按照原来的方式工作。因此,非常重要的一点是数据独立性可以保护已存在的资产,这些资产可以存在于已有的应用程序、用户培训、数据库设计或者其他事情中。

再重复一下,DBMS是逻辑数据库和物理数据库之间的一个媒介。换句话说,它支持通向数据库的接口(interface)(在本书中的其他地方,我一直不加限制地使用数据库[database]来专门表示逻辑数据库,除非在上下文环境中另有要求)。因此,DBMS 的主要职责包括:(a)负责接收用户请求,这些请求可以是查询或者修改,具体形式要根据逻辑数据库的要求来决定;(b)通过解释或执行的方式对这些请求做出响应,换句话说,就是根据物理数据库的形式来执行这些请求。注意:在极少的情况下[4],术语修改(update)一般用来指的是插入新数据、删除或修改已存在的数据等这类请求。

因此,DBMS可以“保护用户已有的数据”(例如,可以保护数据在系统内部真正的存储形式等细节)。我们可以有些得意地说,它保护了用户数据。但是我的真正意思是,它提供了安全性(security)、并发性(concurrency)、完整性(integrity)和恢复等(recovery)控制。简要说明如下。

最后,关于DBMS,我还要说一件事情。从我前面讲解的每一件事情中可以看出,有一点是相当清楚的,那就是数据库之间的逻辑结构是有区别的,它是存储数据的仓库,而DBMS是管理这个仓库的软件。不幸的是,在数据库领域使用术语数据库(database)表示DBMS已经很普遍了[5],但我想强调的是,这个术语已经非常非常普通了,在本书中我不会再采用此种说法。因为如果要把DBMS称为数据库,那真正的数据库又是什么呢,这是个问题。

现在我们已经知道了什么是DBMS,但什么是关系型DBMS呢?当然,首先它是一个DBMS,它要提供本章介绍的DBMS具备的所有功能:数据存储、查询、修改、恢复控制、并发控制、安全控制和完整性控制,以及本书中没有讨论的其他功能。但是第二点要注意的是,它又是关系型的,这就意味着用户接口在真正实现时必须是关系模型。换句话说,关系模型被看作是DBMS中实现用户接口的一种方法。

在继续讲解之前,还要强调一点,这个方法(即关系模型)其实很简单!关系模型的这些方法并不是紧身衣,相反,它们是一种规则,对用户来说可以是生活更加容易的一种规则(在某些方面,对系统来说也更简单,但是重点是针对用户的)。现在,虽然这种方法有时看上去稍复杂些,但最重要的是,关系模型是很正规的。既然正规就需要有正规的术语,正规的术语有时会令人却步。但是术语中的这些定义实际上相当简单(别忘了,供应商和零件数据库就相当容易理解,不是吗?)。事实上,我们谈论的这些定义要比过去使用的类似定义简单得多,就像IMS和IDMS这样的前期关系系统或非关系系统[6]

再重复一下,关系型数据库管理系统是支持真正实现关系模型的用户接口的DBMS。对用户而言,其含义如下。

   S WHERE CITY = 'London'

这个表达式表示查询供货地点在London的供应商,它使用了关系型的“限定”运算符。规范的表达就是,它请求在表S中查询地点在London的供应商集合。

然后,在本书的第一部分中,我们将仔细看看“数据看上去是关系型的”的真正含义,我们也要检验各种关系运算符,看它们是否能起到作用。然后,要注意的是,这种解释也不一定是非常详尽的(这些主题的详尽解释可以参照 SQL and Relational Theory),但是就现状来说,它是非常综合的,也是非常准确的。

不幸的是,这里还有一个问题。为了说明这些定义,我们还要讨论一些问题,即我需要明确给出一些编码实例。为了表达这些实例,我需要采用正式的语言来描述,但是关系模型没有规定任何一种这样的语言,而且它是在很高的抽象级别上定义的,原则上是能够来具体实现任何不同的语法形式。现在,一种标准的、具体的语言确实存在了,即SQL,目前在市场上它也或多或少地获得了所有主流数据库产品的支持。然而就像在前言中提到的,SQL是有很多缺点的,比如它的复杂性、不完整性、难掌握,在很多方面还容易造成误导。因此我计划编写本书的目的如下。

(第二部分是对前言中提到的问题所做的简短说明)注意:也许我应该声明一下,由于前面提到的计划,接下来进行的工作可能与目前市场上的大部分书籍或报告不太一样,所以我打算叫做“关系数据库的介绍”。

在结束本节前,再说明一点。你也许知道,但也许不知道(但是我希望你知道):关系模型最早是由E.F.Codd发明的,当时他还是IBM的一名研究人员(E代表Edgar,F代表Frank,但他一直喜欢用首字母签名,作为他的朋友,我也感到很骄傲)。1968年末,Codd已经成为了一名数学家,他第一次实现了数学定律可以用来把一些固有的原理用在某一领域中,例如,数据库管理,而在以前这些都是做不到的。他在关系模型上最初产生的一些思想可以在1969年IBM的研究报告中找到(进一步的研究可以参见附录E)。

这两个概念好像不太好区别,但是也有一些相似性。事实上,通常不认为一个数据库系统就是一个程序系统(更确切地说,是一种特例)。图 1.3 给出了代码片段,这段代码的目的是要计算一维数组A中整型数据的和,并将其显示在终端上(该片段采用一种假设的语言来表示,但该语言具有自解析性)。

图1.3 代码片段

相关说明如下。

最后要说明的是,之所以详述这些大家已经相当熟悉的知识,是因为所有以前出现的概念都是和数据库直接相关的,这些在接下来的内容中将会看到。

首先,对于类型的定义,我尤其要多讲一些。图1.3所示的代码片段不能解释这一点,但是通常情况下,类型或者由系统定义,或者由用户定义,它们也可以任意组合。例如,在一些几何应用中,用户也许会定义如下类型:POINTLINERECTANGLECIRCLE等。然而,对于只是使用它们的用户(与实际定义它们的用户是相对而言的)来说,这些定义类型的用户更能准确地去认识系统。所以,在这本书后面我所提供的例子中,为了尽量减少失去或不失去通用性,我限定大部分情况下只能定义的类型有INTEGERCHAR,但不完全是这样。

其次,我曾经说过,每个值都是属于某种类型的。它要把每个变量、每个参数赋予每个运算符、每个只读运算符或者每个表达式(尤其是每个符号和每个变量引用),这些运算符也是属于某种类型的,因为有这些结构存在,所以使用它们时肯定会声明某些值。具体说明如下。

第三点,也是最后一点,理解与给定类型T的关系,这一点很重要。对于类型T,定义了一组操作符的集合,要操作类型T中的值和变量(因为没有操作符的类型是无用的)。例如,对于类型INTEGER而言,为简单起见,我只定义系统,由代理负责定义类型。换句话说,该系统必须定义如下内容。

理解给定类型T中必须包含赋值和等式子、比较是非常重要的,而且,这些运算符的语法必须要满足下述条件。

注意:对于“:=”和“=”这两个运算符,它们的等价性是非常重要的。因为没有它,我们就不能讨论值v和值的集合S,不管v是否出现在S中(例如,判断v是否是S的元素)。

最后,我再重复一下,之所以详细讨论我们已经相当熟悉的知识,是因为所有的定义都是直接与数据库相关的,这一点在下面的章节中将会看到。

现在到了该做练习的时候了。当然,在本书中的第1章就进行查找练习是不可能的,下面大多数是复习题。尽管如此,我还是建议你们尽力独自去回答问题,而不要去看后面给出的答案。注意,前两个练习似乎有些不公平,因为我还没有提供足够的知识让你们去正确回答它们,但是我认为你们应该了解一下,它们并不难。

1.1 下面的Tutorial D表达式的含义是什么?

   a. P WHERE WEIGHT < 12.5

   b. P { PNO , COLOR , CITY }

1.2 写出Tutorial D下面语句的功能。

   a. DELETE S WHERE STATUS = 10 ;

   b. UPDATE S WHERE STATUS > 10 : { STATUS := STATUS + 5 } ;

1.3 什么是数据库?什么是DBMS

1.4 解释下列术语:(a)安全控制;(b)完整性控制;(c)并发控制;(d)恢复控制。

1.5 什么是SQL?什么是Tutorial D

1.6 用自己的话解释下列概念。

1.7 (不参考本章内容的前提下独立完成)供应商和零件表数据库中包含哪些表?都有哪些列?注意:该练习的重点是让你尽可能熟悉数据库的结构,至少是采用通用的术语来理解,但不需要去记住数据库中存储的数值。

1.1 a.找出重量小于12.5的零件。这个例子中用到了关系限定运算符。b.给出每个零件的编号、颜色和所在城市。这个练习确实有些不公平,但也许你能猜出答案。正如限定运算可以选出特定的列一样,该例子中给出的投影操作也可以选择出特定的列。我们将在第4章给出进一步的解释。

1.2 a.删除所有状态等于10的供应商。b.把状态大于10的供应商的状态值都增加5。顺便说一下,注意该例子中关键词UPDATE的用法。也许你有一点儿糊涂了,在数据库领域中,使用大写形式如UPDATE来指代改值操作的运算符已经成为一个标准(与之对应,DELETE代表删除已存在的数据,INSERT代表插入新数据),小写形式update代表运算符集合INSERT、DELETE、UPDATE。因此,在本书中,当用运算符UPDATE时,我将采用大写形式。对于INSERT、DELETE,则不会产生歧义,如果使用大写形式,有时会觉得多余,特别是在它们只是作为一个修饰语存在的时候,例如“INSERT语句”(是否可以使用“insert语句”)。因此,我决定在本书中这两种形式都采用,但要根据上下文环境来区分其具体的含义。

1.3 数据库就是采用电子化的形式存储数据的仓库。DBMS是一个软件系统,它管理数据库并可以访问这些数据库。

1.4 安全控制就是保护数据库不受到非法操作;完整性控制就是保护数据库接受经过认证的、有效的操作;并发控制是保护用户的操作,使其不产生相互影响;恢复控制是保证数据不丢失。

1.5 SQL 是一种可以和关系数据库进行交互操作的标准化语言。目前,市场上的主流数据库都支持此种语言。Tutorial D 是一种专门为解释关系型概念而设计的语言,原型实现确实是存在的(可以参见网站www.thethirdmanifesto.com),但是,在写本书的时候,还没有形成商业性的产品。

1.6 类型就是一组值的集合。一个值就是一个独立的常量,例如,整数3是不能改变的。变量就是一些值的容器,它可以被改变。例如,它的当前值是可以被另一个值所替代的。一个符号就是一个自我定义的一种标志,用来表示一个值。例如,数值3。赋值是一种运算符,它可以改变一个变量的值。比较就是一种只读运算符,它可以在两个值之间进行对比,然后返回一个布尔值。更新运算符可以修改某些变量的值,换句话说,它也是一种赋值。注意,在练习1.2的答案中提到的运算符INSERT、DELETE、UPDATE都是关系型的更新运算符,因而都采用关系型的赋值来定义。进一步的解释说明可以参见第2章。

1.7 参考图1.1。

[1] 这里仍然指的是计算机专业人员,而不是一个天才的“终端用户”,他可能会合理地忽略掉本书中讨论的大部分内容。

[2] 本书的前言中曾提醒读者,在本书中我将用缩写形式“SQL and Relational Theory”代表我的著作SQL and Relational Theory: How to Write Accurate SQL Code(第二版,O’Reilly, 2012)。

[3] 顺便说一下,虽然物理数据库不如逻辑数据库抽象,但它仍然是经过抽象后形成的。它一般包含很多成分,如存储的文件或索引,这些存储的文件或索引以一种更低级别的方式来表示,如页或磁盘空间。页或磁盘空间相应地又是一些更低级别组成成分的抽象,如二进制位或字节,当然,它们本身也是一种抽象(抽象的级别可以很深,只要你能想像的到)。

[4] 这种极少的情况是很重要的,参见本章后面的练习1.2。

[5] 一个典型的例子,大家几乎可以在Internet上随处看到这样一种现象:“MySQL 是世界上最受欢迎的开源数据库”。但是它不是,它也许是世界上最受欢迎的开源数据库管理系统(我也不太清楚),但不是数据库。

[6] 这要比各种建议中提到的类似定义简单多了(但这种犯错太频繁了,这样说我感到非常抱歉),这是因为有关系模型作为替代(例如:XML、NoSQL、角色模型等)。顺便说一下,我从来没有看见过这样一种建议,即提出这种建议的人真正理解了关系模型。可以肯定的是,如果你想声明技术A不好,需要用技术B替代,那么对于你来说首先理解技术A就是一项义不容辞的职责,尤其是要证明技术B如何解决了特定的问题,而技术A不能解决。

[7] 在本书第一版出版之后,Tutorial D已经修订并扩充了一些内容。修订版本的描述(在本书中我采用的就是修订版)可以在Hugh Darwen和我的另一本书中找到,即Database Explorations: Essays on The Third Manifesto and Related Topics (Trafford, 2010),也可以参见网页:www.thethirdmanifesto.com。

[8] 事实上,是属于一种特定数据类型,除非有类型继承关系,但在本书中是不存在类型继承关系的。注意:类型是不能相交的(至少我们所关心的就是),即没有一个值会同时属于2个或者多个类型。

[9] 这样就会出现一个很明显的问题,即是否还有类似于这样特性的运算符,但它是不是只读的呢?答案当然是肯定的。修改运算符就是在被借用时不返回值,但是修改一些变量。然而,我们将会在后面看到,任何给定的修改运算符的借用在功能上都等价于一个赋值操作。从逻辑上讲,赋值就是我们需要的修改运算符。


没有什么可以像关系一样去处理问题。

——写给William Makepeace Thackeray的歉语

Vanity Fair(1847~1848)

在这一章中,我想向大家清楚地解释在第1章中提到的数据“看上去是关系型的”的真正含义。换句话说,我想要确切地解释什么是关系。首先,我需要向您展示一些曾在前面章节讲过的事情,即(a)关系模型是最精确的;(b)这种精确需要精确的或规范化的术语;(c)这种规范化的术语让人感觉有点畏惧(它真的会成为理解过程中的一个障碍)。但是这些术语中提到的概念却是相当直观的。在你和这些规范化斗争的时候,我希望你已经做好准备去付出必要的努力。

我们再重温一下供应商和零件数据库(如图2.1所示,它和图1.1所示是一样的),从关系型的视角来看,以前在数据库中被称作的“文件”或“表”其实都是关系。现在,关系就是一个数学上的概念,它有一个非常精确的数学定义,在本章结束时我将会给出这个定义,现在我们知道关系被描述成表的形式就足够了。每一种关系都由标题和内容组成,即:

图2.1 供应商表和零件表数据库——样本数据

下面我们就仔细看看什么是属性和元组。

属性由名字和相应的类型组成(更规范地说,属性是由属性名和类型名组成的偶对)。例如,供应商关系有一个属性,它的名字为STATUS,它的类型名为INTEGER,这就意味着属性的合法值都是INTEGER,而且只能是INTEGER

在这个定义中我要强调下面两点。

供应商关系中的属性如下所示:

SNO  :SNO
SNAME :NAME
STATUS :INTEGER
CITY  :CHAR

上面给出的每一对中的第一个名字是属性名,第二个是相应的类型名,在此例中我假设类型SNO(指的是供应商编号)和SNAME(指的是供应商的名字)是用户已经定义的类型,类型INTEGER(所有合法的整型值的集合)和CHAR(所有合法的字符串的集合)是系统定义的。但是,现在我要提醒您的是,在第1章中提到这个例子时,用户定义的类型是假设被看作是系统已经定义好的(至少对于使用它们的用户来说是这样,但对于真正定义它们的用户来说不是这样的)。所以,从这一点上来说,我还要进一步简化这个例子,假设属性SNOSNAME都是CHAR(这个类型是系统已经定义的)类型的,即:

SNO  :CHAR
SNAME :CHAR
STATUS :INTEGER
CITY  :CHAR

事实上,在本书中对于用户定义的类型我没有解释太多。这种简化可以允许我忽略很多细节,而这些细节对于定义类型的人来说是很重要的,但对于使用类型的人是不重要的(对于关系型数据库来说也不重要)。

因此,供应商关系的标题就是一组集合,即:

{ SNO CHAR,SNAME CHAR,STATUS INTEGER,CITY CHAR }

这就是Tutorial D的标记方法。就像你看到的那样,在Tutorial D的标题中,我们使用一个或者多个空格代替冒号来分隔属性名和类型名;使用逗号(后面可以带有0个或多个空格)来分隔每个属性;使用大括号(“{”和“}”)来把这些属性对封装起来。在论文中对于集合的常用表示就是采用大括号来封装元素,而元素是采用逗号分隔的。

语法说明前面的这个段落包含了本书中第一次提到的有用的术语(commalist),而且后面还要多次使用。它的定义如下:假设xyz表示一种语法结构(例如:表示属性),那么术语xyz commalist就代表0个或多个xyz的序列,该序列中的每一对相邻xyz的都用逗号分隔,在逗号之前或之后可以添加一个或多个空格。

给定标题中属性的个数称为度(degree),因此,我们可以把供应商和零件数据库中供应商关系的度称作为4、零件关系的度为5、供应关系的度为3。注意:如果关系r的度为n,那我们就称它为n元的。如果n=1,则称为一元关系;如果n=2,就称为二元关系;如果n=3,就称为三元关系;以此类推。

最后一点要说明的是,就像我们前面看到的那样,一个属性一经定义,就必须是属性名和类型名的偶对。然而,在非正式的场合中,我们通常都是以属性名来单独标识属性,比如说STATUS属性(位于供应商关系中)。同样,我们在表示标题时,通常用属性名的集合来代替属性名和类型名的偶对,因此供应商关系就可以表示为{SNO,SNAME,STATUS,CITY}。这种简化或者简写可以节省很多多余的话。而且,这也是符合语法的,因为还有另一条规则(在这之前没有提到过,但是通常都是这样理解的),即在某种程度上,在给定的标题中,不允许两个不同的属性使用相同的属性名。

给定关系中的每一个元组都要对应于该关系中的标题,这样每个元组就会包含一个可用类型数值,对于每个属性都是如此。例如,供应商关系的主体就是元组集合,即供应商S1、S2、S3、S4和S5,这个五元组中的每个元素都包含一个值,这些值对应于属性SNO、SNAME、STATUS和CITY。而且这些值都是来自于可以使用的类型中的值,分别为CHAR、CHAR、INTEGER和CHAR。注意:其实还可以采用更简单、更准确的一种方式表示,即把这些元组中的每个成员都赋予一个相关的标题,这是因为元组实际上就是有标题的,就像关系中定义的那样。

给定关系中元组的数量叫做关系的基数(cardinality),该定义既适合于给定的数据库,也适合于该数据库中的每一个关系[1]。因而,我们可以说图2.1给出的供应商和零件数据库中供应商关系的基数为5、零件关系的基数为6、供应关系的基数为12。注意:如果基数为0,则该关系就是空的。一个空的关系就像是不包含任何记录的文件一样。

因此,我说偶尔也会发生关系中不含有任何元组的现象。它包含一个定义体,反过来定义体中也包含元组。但实际上我们通常讨论的关系中都含有元组。

关系和元组我们就讨论到这里,现在准备讨论关系本身。我想要说的最重要的一点是,关系是非常精确的、被规范定义的,因而,它们享有大量的规范的特点,无论从理论上还是从实际上来说,这些特点都是相当重要的。注意:就像我在别的书中写到的那样(例如:SQL and Relational Theory一书),它让我相信理论是可行的!从其自身来看,关系理论的目的不仅仅只是作为一种理论,而且,该理论允许我们建立100%可行的系统。这就是我非常相信它的原因,特别是在关系型的环境中,离开这些基础理论就是一个天大的错误。所谓的“关系型”系统至少是有一点吸引力的,但实际上,从这一点上来看,他们已经偏离了基础理论。

尽管如此,还是要讨论关系的4个特点,我先列出它们,然后再一一进行解释。

关系中不包含重复元组。这个特点说明了一个逻辑上的事实,即关系被定义为集合,而从数学上来说,集合中不包含重复的元素。

每个关系中的元素是无序的,从上到下排列。这个特点也是一个逻辑上的事实,即关系是一个集合,但在数学上规定集合中的元素是没有次序的(例如,{a,b,c} 和 {c,a,b}是等价的)。当然,当我们把关系表示成一个表格时(例如,在纸上),我们是按照从上到下的次序来排列这些行的,但是这个次序是任意的,你可以不考虑它。例如,图2.1中描述的供应商关系表,表中的行是没有任何次序的。我们可以先描述S3,然后描述S1,之后可以依次描述S5、S4、S2,这和图2.1表示的是同一个关系。因此要注意,在关系中没有“第1个元组”、“第5个元组”、“第87个元组”的说法,也不会说“下一个元组”。换句话说,这些元组没有位置的定义,也没有“下一个”的说法。(注意,偶尔我们规定了这样的次序,是因为我们需要一些特定的、附加的运算,例如,“检索第n个元组”、“插入一个新元组”、“把这个元组从这儿移到那儿”等等。在第7章中我们将会特别介绍这个问题。)

每个关系中的属性是无序的,从左到右排列。同样,关系中的属性也是无序的,从左到右排列,这是因为标题也被定义为集合。当然,当我们把关系表示成一个表格时(例如,在纸上),我们是按照从左到右的次序来排列这些列的,但是这个次序是任意的,你同样可以忽略它。例如图2.1中的供应商关系,是按照从左到右的次序排列每一列,即STATUS、SNAME、CITY、SNO,这和图2.1表示的是同一种关系。因而,不会有“第1个属性”、“第2个属性”、“下一个属性”的说法(例如,在属性中不会有“下一个”的定义)。关系的属性通过名字标识,而不是它们的位置[2]

关系总是规范化的(例如,第一范式的缩写为1NF)[3]。在非正式的情况下,这里所有语句的含义都是在说,我们所讨论的关系中的每一个元组都是与相应的标题一致的(这一点我们早已经知道了)。所以,一个明显的问题就是关系可以是非规范化的吗?答案是否定的。“非规范化的关系”从术语上来讲就是矛盾的。然而,表格可能真的是非规范化的,这与关系正好相反。这部分内容我将在此书的第三部分详细讲解。

我们再来看看图2.1,该图给出了3个关系,即在某个特定的时间数据库中已经存在了这些关系。但是如果换个不同的时间再来看看这个数据库,我们也许会看到不同的关系。换句话说,这些在图中标识为S、P、SP的对象实际上是变量,明确地说是关系变量。像所有的变量一样,它们在不同的时间会具有不同的值。因为按照特性划分,它们是关系变量,所以在任何给定的时间,它们的值也是关系型的数值(如图2.1所示,给出的是3个关系型的数值)。

现在,因为S、P、SP都是真正的变量,它们当然也可以被修改、被赋值。(像第1章提到的,变量可以被赋值,也可以把值赋给变量。)例如,假设变量S当前具有的值如图2.1所示,然后,假设我们执行下面的关系型赋值:

S := S WHERE CITY ≠ 'London';

和所有的赋值语句一样,上面语句的作用是计算右边表达式的值,然后把结果赋值给左边的目标变量。所以,关系变量S的值如下所示:

换句话说,供应商S1和S4的元组(二者的CITY属性值都为London)都被删除了。事实上,前面的赋值语句与下面的DELETE语句是等价的:

DELETE S WHERE CITY = 'London' ;

因而,这个DELETE语句是比前面的赋值语句更友好的一种“速记”方法(“速记”加上引号,是因为它实际上要比所期望的缩写长一些)。然而,这也没有关系(不管修改操作是被规范化为关系型的赋值,还是采用更为友好的以这种速记方式来表示),因为从概念上来说都是S的旧值已经被新值完全替代了。旧值(带有5个元组)和新值(带有3个元组)很明显是不一样的,它们具有不同的值。

实际上,现在关系型的DBMS都支持作用于关系变量的INSERT、DELETE和UPDATE运算符,至少从概念上来说,这些运算符都只是特定关系型赋值的一种速记方法。从逻辑上来说,在关系型赋值运算中我们只需要修改运算符(这一点我将在第4章中做出说明)。现在我来更多地展示一些速记方法的例子,第一个就是另外一个DELETE的例子:

DELETE SP WHERE QTY < 150 ;

对于这个DELETE的结果,我将其作为练习留给读者,样本数据如图2.1所示。

下一个例子是INSERT:

INSERT SP RELATION { TUPLE { SNO 'S5' , PNO 'P1' , QTY 250 } , 
           TUPLE { SNO 'S5' , PNO 'P3' , QTY 450 } } ;

INSERT运算的结果是把一个由2个元组组成的关系插入到关系变量SP中。假设这个变量的初值就是图2.1所示的供应关系,那么执行INSERT后,这个关系的基数就变为14,即12个已存在的元组再加上2个新的元组。

最后一个例子是UPDATE:

UPDATE SP WHERE SNO = 'S2' : { QTY := 2 * QTY };

仍然假设关系变量SP的初值为图2.1所示的关系,执行UPDATE后,会得到一个不同的关系,因为供应商S2的QTY值翻倍了。顺便提一下,要注意该语句中的属性赋值QTY := 2 * QTY(要放在大括号内)。

再强调一下,实际上现在关系型的DBMS都支持作用于关系变量的INSERT、DELETE和UPDATE运算符,尽管存在这个事实,但至少从概念上来说,这些运算符都只是特定关系型赋值的一种速记方法。然而,一定要注意,所有这些运算符的运算对象(包括关系型赋值)不是一个关系值,而是一个关系变量。相比之下,我们前面章节中提到的限制和投影这样的运算符是对关系值进行操作的。(当然,限制、投影以及我们将在第4、5章讨论的其他运算符都是只读运算符,然而INSERT、DELETE和UPDATE是更新运算符。对于这两类运算符的差异,请参见第1章。)

总结一下,关系值和关系变量之间是有逻辑上的差异的。为此,接下来我要更加详细地对二者加以区分。当讨论关系值时就使用关系值,讨论关系变量时就使用关系变量。然而,大多数情况,我也会把关系值(relation value)简写为关系(relation)(就像我们把整型值[integer value]简写为整型[integer]一样)。同时,也会把关系变量(relation variable)简写为relvar,例如我说供应商和零件数据库中包含3个relvars[4]。注意:术语relvar没有被广泛使用,但实际是应该被广泛使用的。

最后一点,通常用R表示一个关系变量。就像关系一样,R具有特定标题H(这是一个别名,具有特定的属性和特定的度)。定义R后,标题H就是固定的(参见第3章),被合法赋值给R的每个关系r必须具有相同的标题H。而且,在某一特定时间t,把关系r赋值给R,那么r的定义体、元组、基数就是在时间t的R的定义体、元组和基数。因此,关系变量的定义体、元组和基数是随着时间变化的,而标题、属性和度是不变的。

判断下面的叙述哪个是正确的?

2.1 关系(以及关系变量)中的元组是无序的。

2.2 关系(以及关系变量)中的属性是无序的。

2.3 关系(以及关系变量)不能有任何未命名的属性。

2.4 关系(以及关系变量)不允许有2个或多个属性同名。

2.5 关系(以及关系变量)不包含重复的元组。

2.6 关系(以及关系变量)总是1NF的。

2.7 已定义的关系型属性的类型可以是任意复杂的类型。

2.8 关系(以及关系变量)本身是具有类型的。

附加题:

请尽量清晰地给出关系的定义。

练习2.1~2.8都是正确的。具体说明如下:练习2.1、2.2、2.4、2.5和2.6都可以用本章的知识来解释。练习2.3也是毫无疑问的,因为属性就是采用属性名和类型名的偶对定义的,从叙述上来说,一个未命名的属性是矛盾的。现在就剩下练习2.7和练习2.8了。

我们首先来看一下练习2.8,“关系(以及关系变量)本身是具有类型的”。就像我刚说的,这句话是正确的。当然,实际上关系就是一个值,而关系变量就是一个变量,从第1章中我们知道每个值都是属于某种类型的,每个变量也是属于某种类型的,所以这句话明显就是正确的。但是在本章中对于关系和关系变量类型本身我故意什么都没有说,因为我想把它们放在第3章中来讨论,在第3章中我将做进一步的解释。

现在来看看练习2.7,“已定义的关系型属性的类型可以是任意复杂的类型”。同样,我也说过这句话是正确的。我们可以有包含值的、具有属性的关系和关系变量,这些值可以和我们想象的一样复杂。例如,这些值可以是多边形,可以是数组、XML文档、照片、音频或视频记录等。然而,它也有许多限制:

至于术语关系的精确定义:首先我们给出术语元组的准确定义,如下:

定义T1T2,…,Tnn≥0)表示类型名,与每个Ti相关的Ai表示不同的属性名,n个属性名和类型名的组合中的每一个都是属性。与每个属性相关的属性值记为Vi,其类型为Tin个属性和值的组合中的每一个都是一个元素。这n个元素的集合就定义好了,t是一个元组值(或者简称为元组),它具有属性A1A2,…,Ann就是t的度,度为1的元组是一元的,度为2的元组是二元的,度为3的元组是三元的,以此类推,度为n的元组是n元的,所有n个属性的集合就是t的标题。

现在我们定义关系:

定义:H表示元组的标题,t1t2,…,tmm≥0)是不同的元组,都具有标题H。具有标题H和元组集合{t1t2,…,tm}的组合就是关系值(简称为关系),记为r。这些元组的属性为A1A2,…,Anr的标题是H,r具有和标题一样的属性(因此也具有同样的属性名和类型)和度。元组集合{t1t2,…,tm}是r的定义体,值mr的基数。

[1] 参见第3章的脚注,关于“每一个关系”的含义的解释。

[2] 实际上,不需要我们关心的真正原因是,数学中定义的关系是把属性按照次序从左到右的次序排列的(参见附录C),并不像关系模型中定义的。

[3] 你可能知道,有第一范式,就有可能定义更好一级的范式,如第二范式、第三范式等,这与数据库的设计规则有关。在本书的第二部分我将会介绍该内容。

[4] 更确切地说,是3个真正的或者基本的关系变量。这是为了把它们和虚拟的关系变量或视图加以区分(进一步的讨论可以参见第3章和第7章)。

[5] 理解我们这里讨论的是关于第1章中提到的“逻辑数据库”。相反,物理数据库几乎都要包含指针,而且还很多,但是这些指针对于用户来说是不可见的(用行业术语解释,就是被封装了)。


相关图书

数据模型记分卡
数据模型记分卡
视图更新与关系数据库理论
视图更新与关系数据库理论
图数据库(第2版)
图数据库(第2版)
图数据库
图数据库

相关文章

相关课程