|
|
|
|
移动端

2.1 关系和关系变量

《视图更新与关系数据库理论》本书详细介绍了数据库架构的设计和实现,同时讨论了视图更新及关系数据库理论。本节为大家介绍关系和关系变量。

作者:田远帆 译来源:人民邮电出版社|2018-01-25 17:17

技术沙龙 | 邀您于8月25日与国美/AWS/转转三位专家共同探讨小程序电商实战

第2章 技术背景

适合我的一切也应该能适合你。

——Walt Whitman《Leaves of Grass》(1885)

上一章的讨论是基于SQL的,因为大家对它都很熟悉。但实际上很可惜,SQL并不适合作为这种探究的基础,也无法满足目前手上课题对细节技术讨论的要求。一方面来讲,我们需要检验的概念很多时候完全无法用SQL语句表达;从另一方面来看,即使是可以表达的时候,SQL通常也会引入一大堆与之毫无关系而又没有必要的复杂内容,很容易使人一叶障目,不见森林。由于以上原因,在本文余下部分中,我将不会使用SQL作为论述基础(不过有些地方我还是要针对SQL做出一些说明),而是使用一种假想的语言,名字叫Tutorial D[1]。我相信现在这个语言已经广为人知了。不过,如果你需要一个比较综合的解释说明的话,可以在我和Hugh Darwen合著的《Databases, Types, and the Relational Model: The Third Manifesto》(第3版,Addison-Wesley出版,2006)[2]这本书中找到。

正如上面这本书的标题所写,后文中我会用“关于宣言的那本书”作为简称来引用,它还为大家介绍和解释了“第三宣言”,这是一个很精准的对于关系模型和支持类型理论(也包含了一个关于类型继承的复杂模型)的正式定义。在那本书中,我们使用“D”作为所有能够符合“宣言”原则要求语言的通用名。许多优秀的语言都够得上“D”的资格,很可惜,SQL是个例外。反观Tutorial D就是一个合格的“D”。实际上,Tutorial D原本就是被设计为一个说明和讲解“宣言”理念的合适载体,它也同样适合在本书中作为我研究的基础语言。因此,虽然我的说法是本书中的讨论要以Tutorial D为基础,而其实更准确的说法应该为这些讨论本质上是建立在“宣言”的理念基础上的。本章的其余部分包含一个关于这些理念想法的调查(当然,调查并不包含与我们的文章主题关系不大的那些观点)。换句话说,它主要是由一些你可能已经比较熟悉的内容组成的。即使如此,这一章仍然值得你至少“从头到尾马马虎虎地”读一遍,只要能对后面章节所倚重的概念和名词做些了解就可以。

2.1 关系和关系变量

每一个关系都有一个“关系头”和一个“关系体”,其中关系头是一系列状态和特征,而关系体则是符合关系头的一系列数组。让我们再次使用“供应商与零部件”数据库(如图2.1所示,与第1章的图1.1完全一样),供应商关系的关系头是{SNO CHAR, SNAME CHAR, STATUS INTEGER, CITY CHAR}的集合,我们假设在这里确定属性SNO、SNAME、STATUS和CITY分别被定义为CHAR、CHAR、INTEGER和CHAR这几种数据类型,而这个关系的关系体是对于供应商S1、S2、S3、S4和S5的数组的集合。这里要注意,每个数组都符合特定对应的关系头的要求,因为它们每个都只包含一个值,分别对应属性SNO、SNAME、STATUS和CITY(并且没有其他内容)。注意:其实更准确,也是更正确的说法应该是每个数组都“拥有”特定对应的关系头,因为在一个关系中,数组是应当有关系头的。

每个关系也都拥有(或者说属于)一个特定的“类型”,而这个特定的类型其实完全是由特定的关系头决定的。因此,我们在Tutorial D中表示一个给定的关系的类型时,其实就是关键词“RELATION”后面跟着适用的关系头。举例来说,供应商关系的类型就是:

  1. RELATION { SNO CHAR , SNAME CHAR , STATUS INTEGER , CITY CHAR } 

接下来我要说,关系本身和关系变量之间存在着逻辑差异[3]。现在我们再来看一下图2.1。这张图呈现了3个关系,也就是说,这3个关系有可能在特定的时间里同时存在于数据库中。但是,如果我们换个时间再来看数据库的话,很有可能我们看到的就是其他的关系。换句话说,S、P和SP都是变量,准确地说是关系变量,它们跟其他变量一样,值会随时变化。那么既然它们是具体的关系变量,那么在给定的时间内,它们的值就是关系值。不过要注意,对于一个给定的关系变量来说,合法的值必须都属于同样的关系类型,例如,这些值必须都有相同的关系头,而这个关系类型和关系头也因此被看作这个关系变量的类型和头。

为了更全面地阐述前面提到的想法和理念,我们假设关系变量S拥有和图2.1所示相同的值,我们再假设现在要删除在伦敦的供应商的数组。

  1. DELETE ( S WHERE CITY = ‘London’ ) FROM S ; 

关系变量S现在应改变成如下的样子。

从概念上来讲,S原来的值(当然是个关系值)已经被一个新的值(另一个关系值)整体替换掉了。现在我们来看,原来的值(有5个数组)和新的值(有3个数组)似乎看起来很像,但是其实它们是完全不同的值。我们用“DELETE”作为刚才操作语句的缩写[4],实际上在这里它等价于下面的“关系赋值”。

  1. :S WHERE NOT ( CITY = ‘London’ ) ; 

或者等价于:

  1. :S MINUS ( S WHERE CITY = ‘London’ ) ; 

那么经过所有这些赋值操作会发生什么呢?我们会看到(a)在右侧的源表达式是需要运算的,而(b)运算得出的值就会被赋给等式左侧的目标变量,于是就会产生我们刚刚讲过的效果。

因此DELETE是一个特定关系赋值的缩写,当然,对于INSERT和UPDATE来说也是相似的,它们从本质上来说也是对于特定的关系赋值的一个缩写。从逻辑上来讲,实际上关系赋值是我们唯一真正需要的更新操作(这是我在下一节要重点说明的观点)。

综上所述:关系本身和关系变量之间存在着逻辑差异。也正因为如此,我在之后也会很谨慎地区分它们二者,当我用“关系值”这个词的时候我就是在指关系的值,而当我说“关系变量”这个词的时候指的就是关系的变量。不过,我大多数时间还是会用“关系”作为“关系值”的简称(就好像我们用“整数”来作为“整数值”的缩写一样)。并且我大多数时间会用“relvar(关系变量,译者注)”来作为“关系变量”的缩写,例如,我会说“供应商与零部件”数据库包含3个“关系变量”(更具体一点来说,是3个“真实”或基础关系变量,之所以这么说是为了把它们和“虚拟”关系变量或者视图区分开)。

基础关系变量定义

下面是Tutorial D对于目前例子中使用的3个关系变量的定义,以供后面参考引用。

  1. VAR S BASE RELATION  
  2.   { SNO CHAR , SNAME CHAR , STATUS INTEGER , CITY CHAR }  
  3.   KEY { SNO } ;  
  4.  
  5. VAR P BASE RELATION  
  6.   { PNO CHAR , PNAME CHAR , COLOR CHAR , WEIGHT RATIONAL , CITY CHAR }  
  7.   KEY { PNO } ;  
  8.  
  9. VAR SP BASE RELATION  
  10.   { SNO CHAR , PNO CHAR , QTY INTEGER }  
  11.   KEY { SNO , PNO }  
  12.   FOREIGN KEY { SNO } REFERENCES S  
  13.   FOREIGN KEY { PNO } REFERENCES P ; 

出于本书的目的,我选择忽略Tutorial D在目前定义中并不包含明确的FOREIGN KEY语法的这个事实。


喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:365934973

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

Ubuntu Linux入门到精通

本书全面介绍了Ubuntu Linux的相关知识,内容详实,论述清晰。主要内容包括Ubuntu介绍、文件系统管理、进程管理、压缩与查询系统、Shel...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊