关系数据库的面向对象特征及其局限
我们平时所说的数据库具体所指就是关系型数据库,这种使用很广的数据库由一个个的二维表组成的。
我们编程序的目的是为了解决现实问题,而现实中的关系何止二维。关系数据库抓住了事物关系的本质,知道再复杂的关系都可以分解来可用二维表表示。因此其对世界的描述力很强。
下面我来说一说关系数据库与面向对象的一些关系。
我们可以把二维表看作一个典型的面向对象设计。
二维表的结构包括:表名称、表头及其默认值、表内容。
其面向对象的特征如下:
表名称 = 概念分类名。(table name = class name)
表头 = 类(class)属性,字段就是默认属性的名称。(field name = default property)
表内容 = 符合这个概念的实体。(object = row)
有时候,我们也称数据库的一行内容为一个实体,实际上暗含了对象的意思。
由此看来,关系数据库,以二维表为表现形式。其实质是暗含了面向对象设计的理念。关系数据库发展出了“范式”的设计要求,实际上就是在要求人们,在设计关系数据表的时候,要遵照清晰的OO思想。
因此,关系数据库对世界的抽象能力是十分强的,这也从侧面说明为什么关系数据库会在众多数据库中脱颖而出,成为大家广泛使用的数据库形式。
但关系型数据库虽然有面向对象的特征,但还是有欠缺的地方。也就是说,不那么OO的地方。
1、无法引用对象。
举个例子,“小张的领导是小王”。这就包含了属性值为对象的情况。小张作为一个对象,他的其中一个属性,即领导,其值为小王。在这里,小王不是仅指“小王”两个汉字,而是小王这个人,即另一个对象。而我们所说的,“那个人的名字叫小王”,这句话也有“小王”两个汉字,这两个汉字才是真正的两个字符。
在关系型数据库中,通过SQL语言或视图可以表达属性值为对象的这个意思。但数据库本身并不能表达出来,需要人为设定,如果数据库设计者忘记了当初的设定,那数据库里的内容就失去含义了。我们需要的是一个本身能进行更复杂表达的数据组织方法。
如果是在编程语言中,一个对象可以将其地址赋给变量,能够直接描述对象与对象的关系。
2、相对固定的概念分类。
学过哲学的人可能知道,意识是物质的反映,我们总是倾向于把同类的东西归纳到一起,从而发现规律。在编程中,我们的归纳行为就是定义class。但大自然的复杂性是无穷的,我们只能在有限程度上认识和归纳。也许今天相类似的东西,到了明天,就显现出差异了,就需要区分开了。这随着我们认识水平的提高和事物的动态变化一定会发生。
当变化发生时,数据库的一部分就只能重新设计,一个表需要拆分为两个表。这种变动会导致一系列的变化,程序、界面、文档、教程。这是耗费不起的。
关系数据库对世界认知的相对固定性与世界的动态性有些不合时宜。如此说来,以JavaScript为代表的动态脚本语言就解决了这一问题,可以随着世界的变化随意定义属性。
3、相对固定的关系。
作为实体,我们可以设置不同的二维表结构,可以存放各种各样的实体,但关系的表达取决于设计者的认识。也就是说,是人为设定的关系。而我们需要的是更为自然的关系,不用设定,他就在那儿。就好像两个人结婚了,那双方亲戚中原来毫无关系的人,一下就有了姻亲的关系是一个道理。
关系数据库需要SQL或视图(本质也是SQL)来定义和描述关系,不能随需要变化。
实际上,我认为,让关系数据库本身来追求面向对象的数据组织方法有些笨拙,而要配合其他的技术,比如编程语言。数据库有其优势,查询语句也很直观,但终究比不上编程语言的灵活与人性化。
在这里,我并不在于评判孰优孰劣的问题,而是互补的问题。程序员需要充分了解什么适合做什么,根据需求将他们有机组合起来,就行了。
如果按照当今中国编程潮流,让数据库去管理极其复杂多变的对象和关系,那恐怕是难为它了。