关于SQL服务器的客户端缓存与O-R映射

为了联接安装在其他计算机上的SQL数据库,常需要在本机上安装数据库驱动,如ODBC驱动程序、JDBC驱动程序。安装在客户端的数据库驱动程序,除了提供用标准API访问不同数据库的接口外,还可以提供重要的缓存功能。

例如,客户端程序用cursor在某一查询的大量结果中来回翻寻时,在往上翻页检查前面看过的结果时,安装在本地的数据库驱动可以从缓存中提取数据,而不必再耗费服务器资源。再如,客户端已经查出的一个顾客的详细资料,如果未经改变,再次查询时也可从本地缓存中获取。又如,本地程序在一个transaction里对一个顾客的资料所作的多步修改,可以被暂存在客户端,直到用户提交操作才发到服务器。使用本地缓存对客户端是透明的,不需要另外编程。(Cache的英文发音与cash相近。)许多应用程序有单独的数据层,用以缓存从数据库读出的数据,这增加了程序的复杂度与运行代价,并且与数据库的同步并不容易严格实现,因而是不必要的易错的。

不过,这并不是说标准的SQL语句就是理想的编程接口,大多数程序员仍然偏爱数据体对象(entity object)。他们不愿直接操作数据库表,而更愿意将数据库视为彼此联接的对象的空间。一些标准框架,如Ado.net Entity Framework、Hibernate意图在数据库表与应用程序数据库类之间架设映射的桥梁(Object-Relational Mapping),以满足程序员的心愿。出于下述几个原因,这一作法是愚蠢的。

首先,这是一个“控制反转”,即由程序而不是数据库自身确保数据的一致性。例如,删除某个顾客的资料会联带(cascade)删除他的交易记录,或者删除一个交易记录会自动将其从所属顾客对象资料中去除,都在应用程序层实现,而不是由数据库自动完成。人工映射强行将数据库的责任交给程序员,使他们必须搞懂复杂的配置文件与中间层代码,这实际上是行不通的(mission impossible)。

理想地,应当由数据库提供概念层的设计工具、以及根据设计生成使用数据对象的远程接口(如Java RMI的remote interface)的工具。用户通过这些接口访问生存在数据库中的远程数据对象,而根本不必关心远程数据对象的实现代码、或者复杂的配置。

// 远程接口,由数据库工具自动生成
interface Customer extends java.rmi.Remote {
    long            getCustomerId()      throws java.rmi.RemoteException;
    String          getName()            throws java.rmi.RemoteException;
    void            setName(String name) throws java.rmi.RemoteException;
    DBList<Record>  getRecords()         throws java.rmi.RemoteException;
                    // DBList也是远程对象,也可改用数组。
}
// 用户代码
public void program(javax.naming.Context ctx) throws Exception {
    Customer customer = (customer)ctx.lookup("/mydb/customer/123001");
    for (Record record : customer.getRecords())
        System.out.println("Record # " + record.getRecordId());
}

说明:1)用户程序实际上与本机安装的数据库驱动相联,所以远程对象也在本机,而驱动与数据库的联接仍通过标准的数据库网络接口(port号)。2)若没有transaction隔离,不同客户看到的同一Customer远程对象代表唯一的数据库实体对象,对一个Customer的更改须锁定所有客户端持有的远程实例。3)Transaction的Serializable隔离级别也要求一旦某Customer对象被一个transaction更改,其他transaction必须等待其结束(提交或回滚)后才能修改相同Customer对象;不过,也可采用另一种执行机制,即transaction各自在孤立状态下执行,看不到彼此所作的改动,但在提交时若发现冲突则交易失败。

另一个不应使用人工O-R映射的原因是数据库之间的区别。数据库都支持标准的SQL语言查询接口,并不说明它们都采用相同的储存机制,更不意味着它们仅支持低级别的SQL表概念模型。实际上数据库能够支持更为丰富的功能。例如,一个记账数据库可以支持“明细账”、“总账”、“报表”这样的概念关系,使用户能在此基础上作设计与编写应用程序。

因此,我们需要强调自身特性的商业数据库,需要它们有良好的客户端缓存、以及更为重要的好的概念模型与编程接口和与之配套的设计工具。好的数据库可以提供自身的培训,可以要求用户为其特别功能(向竞争对手)保密。让数据库管理员考SQL Server或Oracle的认证,或者让程序员不厌其烦地研究某个O-R映射框架是没有意义的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值