关系数据库的面向对象特征及其局限

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

2010年05月11日 17:25 "redorange"的内容
关系数据库,以二维表为表现形式。其实质是暗含了面向对象设计的理念。关系数据库发展出了“范式”的设计要求,实际上就是在要求人们,在设计关系数据表的时候,要遵照清晰的OO思想 ...

恩,发现通过DDD中的实体,聚合,值的概念提取的对象属性分解到数据库之后就完全满足3NF了。

不知有多少人知道“图灵机”,它实际上是计算机的理论模型。
它是由图灵这个人想象出来的概念计算器,其组成为一根无限长的纸条,一个带橡皮擦的读写头。人们可以在上面写下运算式,可以无限的写下去,这样就可以算出世界上所有的数学问题。
对应现在的计算机,可以发现,我们的内存实际上就是那根纸条,只是不是无限长,但已经很长了;CPU是带橡皮擦的读写头。
大家会发现这个简单机器的一个有趣特性,即它处理问题的载体是一维的。和关系数据库的二维表比起来,要更简单。但越简单,越能准确的描述世界。
只是区别在于,维数越少,越接近机器(数学),而远离人。一维的数据在内存中,人不容易看懂;二维的数据在数据库中,人经过训练可以看懂;三维的数据就大量出现在我们的现实世界了,人每天都在处理三维数据;三维以上的数据,比如多个对象之间的关系,人们就需要研究、理解。
关系数据库编程的过程实际上就是将多维世界二维化(平面化),通过程序放到内存中进行一维化。

2010年05月11日 21:47 "redorange"的内容
系数据库编程的过程实际上就是将多维世界二维化(平面化),通过程序放到内存中进行一维化。 ...

是的,这是一个抽象方式,但不代表所有抽象方式;而我们往往以为这是唯一的抽象方式而神化它。

2010年05月11日 22:28 "banq"的内容
这是一个抽象方式,但不代表所有抽象方式;而我们往往以为这是唯一的抽象方式而神化它 ...

二维化是可以的,但必须遵照OO的“范式”,这需要人们严加训练。否则,就有可能在以后的某个时间遇到困难。
让编程语言的对象来对多维世界进行多维描述,可以做到直观和一一对应,实际上是减少了编程的难度。
世界有什么,就告诉计算机有什么;世界怎么变化的,就让计算机再现这些变化。这和画家、作家的艺术工作是差不多的。

2010年05月11日 20:57 "oojdon"的内容
恩,发现通过DDD中的实体,聚合,值的概念提取的对象属性分解到数据库之后就完全满足3NF了。 ...
范式理论的确是挺吻合DDD的理念的,只是现实中很多项目就不一定会去遵循。我记得刚开始工作那会,就看到过有个系统,出了代码表之外,业务表就3张,每张超过80个字段。那样的好处就是不用关联,坏处嘛,范式理论说的很清楚了。

2010年05月12日 08:15 "redorange"的内容
世界有什么,就告诉计算机有什么;世界怎么变化的,就让计算机再现这些变化。这和画家、作家的艺术工作是差不多的 ...

讲得很好,能看到和自己认识一样的见解是非常开心的,但愿那些权威也能认识到,从而改变中国软件教育的方式,国人在软件上大进步。

2010年05月11日 17:25 "redorange"的内容
其面向对象的特征如下:
表名称 = 概念分类名。(table name = class name)
表头 = 类(class)属性,字段就是默认属性的名称。(field name = default property)
表内容 = 符合这个 ...

我认为楼主的言论有一点偏了,
“数据库的一行内容为一个实体,实际上暗含了对象的意思”,
只是一种习惯而非技术上的约束,变化频率较高的实体不
安这种方式存储,化行为列。关系型数据是抓住了
事物的本质,但是它并没有约束你的存储结构,你可能认为这样违背了
关系型数据库的设计理念。其实不然,关键是我们是从哪个维度划分关系。

2010年05月12日 12:52 "cuwkuhaihong"的内容
只是一种习惯而非技术上的约束,变化频率较高的实体不安这种方式存储,化行为列。关系型数据是抓住了事物的本质,但是它并没有约束你的存储结构,你可能认为这样违背了关系型数据库的设计理念。其实不然,关键是我们是从哪个维度划分关系。 ...

如果用数据库作为储存工具,当然是可以的。如果只是以存放为目的的话,我建议用文件更方便。
如果用屠龙刀作为切菜工具,当然是可以的。如果只是以切菜为目的的话,我建议用菜刀更方便。
除了储存外,关系数据库还提供了其它更好的功能,这些功能可以让你的程序更好使用和修改。多学习用使用,可以让我们的水平更上层楼。

至于从哪个维度划分关系,这个问题实际上可以多加讨论。这可能体现了仁者见仁,智者见智的情况。正所谓“有一千个读者,就有一千个哈姆雷特”。

我觉得没必要为了技术而技术,为了数据库对象化而对象化,关键看项目,看应用,这样才能体现你的创造力。

2010年06月02日 14:22 "Oberon"的内容
我觉得没必要为了技术而技术,为了数据库对象化而对象化,关键看项目,看应用,这样才能体现你的创造力。 ...

确实,不遵循关系数据库的范式要求,也能编写出程序,也能大把赚钱,但软件质量如何呢?
大家不想把软件质量提高点,应用于更多客户,赚更多的钱吗?

呵呵,樓上估計沒理解我的意思,使用的技術和軟件質量完全沒有關係,用了對象化質量一定好嘛,不用就一定不好嘛。適當的應用使用適當的技術這才是我想表達的意思。

2010年06月03日 16:45 "Oberon"的内容
適當的應用使用適當的技術 ...

嗯,确实无懈可击。