一个数据库的持久性整体规划通常都是不成套的。各种ORM(对象关系映射)工具都能更容易地进行对象和数据结构之间的转换,但没有一个是完美的。这 就是通常所说的“ORM Impedance Mismatch(阻抗不匹配)”。虽然抽象数据库是一个崇高和理想的目标,但没有考虑关系数据库这一事实总是会暴露出来。Joel Spolsky称之为“The Law of Leaky Abstractions(泄露的抽象规律)”。51CTO 编者注:Joel Spolsky是一个美国的软件工程师,他的网络日志“Joel谈软件”(Joel on Software)非常有名,读者人数可以排进全世界前100名。
最简单的分离形式是由“映射层次对象到数据库表”所描述。这件事绝对是可以做到的,对于其实现毫无质疑。花费在设计理想映射的大量努力,也许可以更 好地用于解决真正的问题,而不是在仔细检查问题之前就考虑解决方案。
更多的根据来自于最近发表在DZone的一篇文章。作者抱怨开发人员胡乱编写代码,使得数据库的使用效率超级低。虽然如此,但这样的问题只有在你了 解低层实现的情况下才能暴漏出来。从纯粹的面向对象的角度来看,代码还算可以。
数据库基础
笔者认为关于数据库解决方案的最根本问题来自于这样一个事实,即人们总是默认地拘泥于某一个应用。“我们需要保持持久性。”“那好吧,让我们使用一 个数据库吧[和ORM]”。
虽然RDBMS(关系型数据库管理系统)是一个很好的、成熟的解决方案,但它并不总是最理想的。在认真分析领域问题之前就先选择一个解决方案始终是 错误的。
核心问题是,我们希望能够保存和恢复应用程序中某些数据结构的状态。需要一些关键点用来在各种机器之间共享这些状态(用于可扩展性)。
尝试删除RDBMS
所有尝试都不外乎建立一个所谓的面向对象数据库,这证明,除了RDBMS我们还有别的选择。我们有了一些很酷的工具,如Apache的 CouchDB,它改变了我们考虑数据库的方式。特别是如JCR(针对Java的内容知识库),它提供了存储数据的另一种方法,看起来更像我们真正要涉及 的对象。
所有这些方法都有一个很大的缺点,在某些时候,你会映射一些其他的数据格式到你的对象,是否还要映射属性/ xml文件、元数据(注释),或只是代码。各种系统都能简单完成这个任务,但总有某个地方让人觉得有问题。
很多都只是RDBMS的再包装,本质并不脱离RDBMS。暴露出来的问题是一些查询极其缓慢,而其他的速度却极快。直到你能理解数据库是怎样被使用 的,你才能明白这是为什么。这会导致代码进行修改,以便能以尽可能最快的方式运行,抽象就被打破了。
几年前,笔者曾经试图用Lucene搜索索引取代只读数据库。它实际上运行得相当出色。使用Lucene搜索索引来查询数据比调用RDBMS要快很 多。在特殊情况下,要快2个数量级之多,但还存在其他问题……这个概念从未真正占据主流。无论有多么不方便,都很难打破人们心理上对于数据库解决方案的传 统认识。51CTO编者注:有关Lucene搜索的使用方法,可参考用Lucene做一个简单的Java搜索工具一文。
理想的解决方案
如果你的应用程序只是要维护它的状态,那将会存在理想的解决方案吗?
◆重启之间
◆机群的机器之间
在这样一个世界里,你根本不认为会存在一个持久性机制。你只是编写你的应用代码;设置对象域;机群中某个机器的线程死亡时的恢复处理 。
只是一个梦想?
我们即将迎来2010年。你要知道,现在我们已经有了在一组计算机之间分享系统状态的方法。有办法在一个文件系统中保留状态备份,允许在系统重启或 崩溃时进行恢复。
你应该能够编写你的应用程序,假设它只能够运行在没有崩溃的单个机器上。
具有串行化的解决方案?
使用串行化来简单地保持应用程序的状态,这种办法怎么样?或者基于图像的持久性,如Smalltalk ?
在使用C / C++ 的日子里,我们可以获得对象在内存中的地址,然后把字节地址写到磁盘。这是一种简单的保存和恢复系统状态的方法。Java提供了一个完整的串行化API (地址不能用于安全方面的考虑)。
可以创建一个线程来不断保持串行化数据文件随着应用程序中对象的更新。然而,这种解决方案在一个机群中可能施行得不太好。透明度将会消失。接口被污 染(需要实现串行化的事物)。
虽然简单,串行化可能不会是最好的解决办法,但是,这将会是一个有趣的实验。
共享内存
实现共享内存最明显的方法是建立一个后台进程,保持一组机器内存同步,同时保存一个文件。这将保持各个机器与其他机器同步操作,如果其中一个机器崩 溃(如果它不能从邻居机器读取状态),利用该文件可以进行恢复。
看起来似乎一个虚拟机可能会为实现一个解决方案提供最大的成功机会,通过虚拟机,它能让一些不可思议的事情更容易地发生在内存访问背后,而不是发生 在直接访问内存空间时。
解决方案
因此,现在都存在哪些解决方案?
Oracle Coherence
Oracle用他们的Coherence产品做出了一个很好的尝试。
这个解决方案的问题在于它的实现。在网络间传送整个对象可以迅速让网络达到饱和(如各种HTTP会话共享模式所表现出来的问题)。 Coherence还需要接口,需要对象实现串行化(但这个问题比较小) 。