如果说上一节介绍的对象是静态的话,那么数据访问过程则是从动态的角度了解数据访问的流程和步骤。譬如,客户端应用程序要执行一条SQL语句,需要经历哪些操作呢?本节我们要介绍连接、应用程序、事务、SQL语句等概念。
一般来说,一个客户端在访问数据前,首先要知道访问的是哪台机器上的哪个数据库,这个操作叫做编目(Catalog)。所谓编目,就是在客户端做个注册,把注册机器的动作叫做节点编目,把注册数据库的动作叫做数据库编目。
一旦编目成功,客户端就可以携带用户名/密码连接数据库了,当编目信息与认证信息都正确的时候,数据库连接(Connection)就会被建立起来。对于每一个数据连接,从数据库角度看就是一个应用程序(Application)。
如果在客户端使用同一个可执行文件同时执行10次,尽管这些连接所发起的可执行文件相同,从数据库看依然接收到10个连接请求,也就是10个应用程序,而不是一个。每一个应用程序可以由一个或多个代理(Agent)负责完成。代理是真正运行在操作系统中的线程或者进程,负责真正运行应用程序的请求。
每一个应用程序在同一时刻只能运行一个事务(Transaction)。事务是指一组工作单元(Unit of Work,UOW),指的是一组要么全成功要么全失败的操作。比如工厂从仓库A向仓库B调运货物,第一步操作会是从仓库A的库存中减少货物的存量,而第二步操作是在仓库B中增加等量的存货。但是如果第二步操作失败了(比如仓库满了),那么我们要撤销第一步操作中在仓库A的更改,也就是让两步操作同时失败。同理,如果第二步操作成功了,那么我们会提交这个事务,让数据真实生效。
在每一个事务中,可以包含一个或多个语句(Statement)。其中有的语句可以用来插入数据,有的语句用来更新或者查询数据。当该事务中所有的操作都执行完毕以后,用户可以提交(Commit)或者回滚(Rollback)该事务,确保不会出现数据不完整的状况。
当一个语句从客户端应用程序发起的时候,首先应用程序会使用某种驱动来与DB2服务端交流。这种驱动可以是CLI、JDBC或者ODBC。当一个语句被驱动拿到后,就会被打成一个网络包发送给数据库的接收端。
当服务端接收到这个包的时候,DB2会根据这个包的数据结构解析出SQL语句。然后DB2编译器对这个语句进行解析,并通过优化器中得到执行计划。所谓执行计划就是一组告诉DB2如何运行一个查询(定义数据对象访问的顺序)的数据结构。然后数据库运行时类根据执行计划生成一个包。当执行这个包的时候,DB2引擎就可以从磁盘上相应位置获取数据,或者与其他的表进行关联。当获得结果后,通过先前建立的TCP/IP连接把结果发送给客户端,图2.4所示演示了这个过程。
不论是什么类型的应用程序,也不管是本地还是远程(如果是本地就不是TCP/IP,而是IPC共享内存),其连接方法都没有太大的差异。
总的来说,数据访问流程就是客户端首先建立数据库连接,每个连接相当于一个应用程序,这个应用程序由一个或几个代理负责完成。每个应用顺序执行一些事务处理,每个事务由一条或多条SQL语句构成。
图2.4 SQL语句处理流程